Compare commits

..
Author SHA1 Message Date
Wouter Wijngaards 29a0405c6c tag for release 1.9.0rc1
git-svn-id: file:///svn/unbound/tags/release-1.9.0rc1@5085 be551aaa-1e26-0410-a405-d3ace91eadb9
2019-01-29 08:11:28 +00:00
1463 changed files with 44322 additions and 188110 deletions
-2
View File
@@ -1,2 +0,0 @@
github: [NLnetLabs]
custom: ['https://nlnetlabs.nl/funding/']
-41
View File
@@ -1,41 +0,0 @@
---
name: Bug report
about: Create a report to help us improve Unbound
title: ''
labels: ''
assignees: ''
---
<!--
Thanks for taking the time to report an issue!
Before continuing please make sure that you checked the existing (opened and closed) issues and pull requests to avoid opening a duplicate issue. We would rather prefer to add the information to the existing one. If you are able, feel free to reopen the closed issue afterwards. If not, please create a new issue linking to the old one.
If you rather have a support question and you need guidance on running/configuring Unbound, please refrain from opening an issue and use the community support mailing list instead (https://www.nlnetlabs.nl/support/mailing-lists/).
We would like to keep GitHub issues for possible bugs and feature requests only.
If you are unsure whether an issue is a bug or not, feel free to reach out to mailing list users or open an issue here.
If you are opening an issue, please complete as much of the following sections as possible to give us a better understanding of your situation.
-->
**Describe the bug**
A clear and concise description of what the bug is.
**To reproduce**
Steps to reproduce the behavior:
1.
2.
3.
**Expected behavior**
A clear and concise description of what you expected to happen.
**System:**
- Unbound version:
- OS:
- `unbound -V` output:
**Additional information**
Add any other information that you may have gathered about the issue here.
-31
View File
@@ -1,31 +0,0 @@
---
name: Feature request
about: Suggest an idea for Unbound
title: "[FR]"
labels: ''
assignees: ''
---
<!--
Thanks for taking the time to report an issue!
Before continuing please make sure that you checked the existing (opened and closed) issues and pull requests to avoid opening a duplicate issue. We would rather prefer to add the information to the existing one. If you are able, feel free to reopen the closed issue afterwards. If not, please create a new issue linking to the old one.
If you rather have a support question and you need guidance on running/configuring Unbound, please refrain from opening an issue and use the community support mailing list instead (https://www.nlnetlabs.nl/support/mailing-lists/).
We would like to keep GitHub issues for possible bugs and feature requests only.
If you are unsure whether an issue is a bug or not, feel free to reach out to mailing list users or open an issue here.
If you are opening an issue, please complete as much of the following sections as possible to give us a better understanding of your situation.
-->
**Current behavior**
Is there a current behavior that the feature relates to?
If yes, would you wish the current behavior to change?
**Describe the desired feature**
A clear and concise description of what the feature should be.
**Potential use-case**
Describe how you see this feature being useful to other Unbound users.
-394
View File
@@ -1,394 +0,0 @@
name: Analysis and Ports
on:
workflow_dispatch:
inputs:
start:
description: 'Start analysis and port workflow'
default: 'yes'
required: true
jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- name: GCC on Linux
os: ubuntu-latest
config: "--enable-debug --disable-flto"
make_test: "yes"
- name: Clang-analyzer
os: ubuntu-latest
config: "CC=clang --enable-debug --disable-flto --disable-static"
make_test: "yes"
clang_analysis: "yes"
- name: libevent
os: ubuntu-latest
install_libevent: "yes"
config: "CC=clang --enable-debug --disable-flto --with-libevent --disable-static"
make_test: "yes"
clang_analysis: "yes"
- name: OS X
os: macos-latest
install_expat: "yes"
config: "--enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat"
make_test: "yes"
- name: Clang on OS X
os: macos-latest
install_expat: "yes"
config: "CC=clang --enable-debug --disable-flto --with-ssl=/opt/homebrew/opt/openssl --with-libexpat=/opt/homebrew/opt/expat --disable-static"
make_test: "yes"
clang_analysis: "yes"
- name: ubsan (gcc undefined behaviour sanitizer)
os: ubuntu-latest
config: 'CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover=all" --disable-flto --disable-static'
make_test: "yes"
- name: asan (gcc address sanitizer)
os: ubuntu-latest
config: 'CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address" --disable-flto --disable-static'
make_test: "yes"
- name: Apple iPhone on iOS, arm64
os: macos-latest
AUTOTOOLS_HOST: aarch64-apple-ios
OPENSSL_HOST: ios64-cross
IOS_SDK: iPhoneOS
IOS_CPU: arm64
test_ios: "yes"
config: "no"
make: "no"
- name: Apple TV on iOS, arm64
os: macos-latest
AUTOTOOLS_HOST: aarch64-apple-ios
OPENSSL_HOST: ios64-cross
IOS_SDK: AppleTVOS
IOS_CPU: arm64
test_ios: "yes"
config: "no"
make: "no"
- name: Apple Watch on iOS, armv7
os: macos-latest
AUTOTOOLS_HOST: armv7-apple-ios
OPENSSL_HOST: ios-cross
IOS_SDK: WatchOS
IOS_CPU: armv7k
test_ios: "yes"
config: "no"
make: "no"
- name: iPhoneSimulator on OS X, x86_64
os: macos-latest
AUTOTOOLS_HOST: x86_64-apple-ios
OPENSSL_HOST: iphoneos-cross
IOS_SDK: iPhoneSimulator
IOS_CPU: x86_64
test_ios: "yes"
config: "no"
make: "no"
- name: AppleTVSimulator on OS X, x86_64
os: macos-latest
AUTOTOOLS_HOST: x86_64-apple-ios
OPENSSL_HOST: iphoneos-cross
IOS_SDK: AppleTVSimulator
IOS_CPU: x86_64
test_ios: "yes"
config: "no"
make: "no"
- name: WatchSimulator on OS X, i386
os: macos-latest
AUTOTOOLS_HOST: i386-apple-ios
OPENSSL_HOST: iphoneos-cross
IOS_SDK: WatchSimulator
IOS_CPU: i386
test_ios: "yes"
config: "no"
make: "no"
- name: Android armv7a
os: ubuntu-latest
AUTOTOOLS_HOST: armv7a-linux-androidabi
OPENSSL_HOST: android-arm
ANDROID_CPU: armv7a
ANDROID_API: 23
test_android: "yes"
config: "no"
make: "no"
- name: Android aarch64
os: ubuntu-latest
AUTOTOOLS_HOST: aarch64-linux-android
OPENSSL_HOST: android-arm64
ANDROID_CPU: aarch64
ANDROID_API: 23
test_android: "yes"
config: "no"
make: "no"
- name: Android x86
os: ubuntu-latest
AUTOTOOLS_HOST: i686-linux-android
OPENSSL_HOST: android-x86
ANDROID_CPU: x86
ANDROID_API: 23
test_android: "yes"
config: "no"
make: "no"
- name: Android x86_64
os: ubuntu-latest
AUTOTOOLS_HOST: x86_64-linux-android
OPENSSL_HOST: android-x86_64
ANDROID_CPU: x86_64
ANDROID_API: 23
test_android: "yes"
config: "no"
make: "no"
- name: Windows
os: windows-latest
test_windows: "yes"
config: "no"
make: "no"
- name: FreeBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "freebsd"
cross_platform_arch: "x86-64"
cross_platform_version: "14.1"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: OpenBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "openbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "7.5"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
- name: NetBSD
os: ubuntu-latest
config: "no"
make: "no"
with_cross_platform_action: "yes"
cross_platform_os: "netbsd"
cross_platform_arch: "x86-64"
cross_platform_version: "10.0"
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
steps:
- uses: actions/checkout@v7
with:
submodules: false
persist-credentials: false
- name: test_windows
if: ${{ matrix.test_windows == 'yes' }}
env:
LIBEXPAT_FNAME: expat-2.7.0
LIBEXPAT_VERSION_DIR: R_2_7_0
shell: bash
run: |
export unboundpath=`pwd`
echo unboundpath=${unboundpath}
cd ..
export prepath=`pwd`
echo prepath=${prepath}
# parralel build option
export MINJ="-j4"
echo "choco install winflexbison3"
choco install winflexbison3
echo 'LEX="win_flex"'
export LEX="win_flex"
echo 'YACC="win_bison -y"'
export YACC="win_bison -y"
mkdir openssl
echo "curl openssl"
curl -L -k -s -S -o openssl-3.2.0.tar.gz https://www.openssl.org/source/openssl-3.2.0.tar.gz
tar xzf openssl-3.2.0.tar.gz
cd openssl-3.2.0
# remove pod::Usage because we do not need -help or -man output
# from the Configure script, this fixes it for openssl 1.1.1
#echo "Fixup ./Configure by removing use Pod::Usage require"
#sed -e 's/use Pod::Usage//' < Configure > Configure.fix
# ./Configure.fix no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl"
# pacman is used to install for msys2, with
# C:/msys64/usr/bin/pacman -S perl
echo "C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix=\""$prepath/openssl"\" PERL=\"C:/msys64/usr/bin/perl\""
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
# make the libs only, build faster
echo "make build_libs"
#make $MINJ
make $MINJ build_libs
mv Makefile Makefile.orig
# fixup \\ in the installtop to /.
echo "fixup INSTALLTOP"
sed -e 's?^INSTALLTOP=.*$?INSTALLTOP='"$prepath"'/openssl?' < Makefile.orig > Makefile
# install the includes and libs only, build faster
echo "make install_dev"
#make install_sw
make install_dev
cd ..
mkdir expat
echo "curl expat"
curl -L -k -s -S -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz
tar xzf $LIBEXPAT_FNAME.tar.gz
cd $LIBEXPAT_FNAME
echo "./configure SHELL=/usr/bin/bash CONFIG_SHELL=/usr/bin/bash --prefix=\"$prepath/expat\" --exec-prefix=\"$prepath/expat\" --bindir=\"$prepath/expat/bin\" --includedir=\"$prepath/expat/include\" --mandir=\"$prepath/expat/man\" --libdir=\"$prepath/expat/lib\""
./configure SHELL=/usr/bin/bash CONFIG_SHELL=/usr/bin/bash --prefix="$prepath/expat" --exec-prefix="$prepath/expat" --bindir="$prepath/expat/bin" --includedir="$prepath/expat/include" --mandir="$prepath/expat/man" --libdir="$prepath/expat/lib"
# fixup SHELL is treated specially, but SHELZZ is not by make.
echo "Fixup Makefiles by renaming SHELL to SHELLZZ"
mv Makefile Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < Makefile.orig > Makefile
mv lib/Makefile lib/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < lib/Makefile.orig > lib/Makefile
mv doc/Makefile doc/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < doc/Makefile.orig > doc/Makefile
mv examples/Makefile examples/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < examples/Makefile.orig > examples/Makefile
mv tests/Makefile tests/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < tests/Makefile.orig > tests/Makefile
mv xmlwf/Makefile xmlwf/Makefile.orig
sed -e 's/SHELL/SHELLZZ/g' < xmlwf/Makefile.orig > xmlwf/Makefile
echo "make"
make $MINJ
echo "make install"
make install
cd ..
echo "unbound"
cd unbound
echo "./configure --enable-debug --enable-static-exe --disable-flto \"--with-ssl=$prepath/openssl\" --with-libexpat=\"$prepath/expat\" --disable-shared"
./configure --enable-debug --enable-static-exe --disable-flto "--with-ssl=$prepath/openssl" --with-libexpat="$prepath/expat" --disable-shared
make $MINJ
# specific test output
#make testbound.exe; ./testbound.exe -s
#make testbound; ./testbound.exe -p testdata/acl.rpl -o -vvvv
make test
- name: test_android
if: ${{ matrix.test_android == 'yes' }}
env:
AUTOTOOLS_HOST: ${{ matrix.AUTOTOOLS_HOST }}
OPENSSL_HOST: ${{ matrix.OPENSSL_HOST }}
ANDROID_API: ${{ matrix.ANDROID_API }}
ANDROID_CPU: ${{ matrix.ANDROID_CPU }}
run: |
#(already installed) ./contrib/android/install_tools.sh
export ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
echo ANDROID_PREFIX=${ANDROID_PREFIX}
export ANDROID_SDK_ROOT="$HOME/android-sdk"
echo ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT}
export ANDROID_NDK_ROOT="$HOME/android-ndk"
echo ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT}
export AUTOTOOLS_BUILD="$(./config.guess)"
echo AUTOTOOLS_BUILD=${AUTOTOOLS_BUILD}
export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
echo PKG_CONFIG_PATH=${PKG_CONFIG_PATH}
export CONFIG_OPTS="--build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST --prefix=$ANDROID_PREFIX --with-ssl=$ANDROID_PREFIX --disable-gost --with-libexpat=$ANDROID_PREFIX"
echo CONFIG_OPTS=${CONFIG_OPTS}
echo "::group::install_ndk"
echo "./contrib/android/install_ndk.sh"
./contrib/android/install_ndk.sh
echo "::endgroup::"
echo "::group::setenv_android.sh"
echo "./contrib/android/setenv_android.sh"
source ./contrib/android/setenv_android.sh
echo "::endgroup::"
echo "::group::install_openssl"
echo "./contrib/android/install_openssl.sh"
./contrib/android/install_openssl.sh
echo "::endgroup::"
echo "::group::install_expat"
echo "./contrib/android/install_expat.sh"
./contrib/android/install_expat.sh
echo "::endgroup::"
echo "::group::configure"
echo "./configure ${CONFIG_OPTS}"
./configure ${CONFIG_OPTS}
echo "::endgroup::"
echo "::group::make"
# make is here to preserve environment variables
make
echo "::endgroup::"
echo "::group::make install"
make install
echo "::endgroup::"
- name: test ios
if: ${{ matrix.test_ios == 'yes' }}
env:
AUTOTOOLS_HOST: ${{ matrix.AUTOTOOLS_HOST }}
OPENSSL_HOST: ${{ matrix.OPENSSL_HOST }}
IOS_SDK: ${{ matrix.IOS_SDK }}
IOS_CPU: ${{ matrix.IOS_CPU }}
run: |
#(already installed) ./contrib/ios/install_tools.sh
export AUTOTOOLS_BUILD="$(./config.guess)"
echo AUTOTOOLS_BUILD=${AUTOTOOLS_BUILD}
export IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
echo IOS_PREFIX=${IOS_PREFIX}
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
echo PKG_CONFIG_PATH=${PKG_CONFIG_PATH}
export CONFIG_OPTS="--build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST --prefix=$IOS_PREFIX --with-ssl=$IOS_PREFIX --disable-gost --with-libexpat=$IOS_PREFIX"
echo CONFIG_OPTS=${CONFIG_OPTS}
echo "::group::setenv_ios.sh"
echo "./contrib/ios/setenv_ios.sh"
source ./contrib/ios/setenv_ios.sh
echo "::endgroup::"
echo "::group::install_openssl"
echo "./contrib/ios/install_openssl.sh"
./contrib/ios/install_openssl.sh
echo "::endgroup::"
echo "::group::install_expat"
echo "./contrib/ios/install_expat.sh"
./contrib/ios/install_expat.sh
echo "::endgroup::"
echo "::group::configure"
echo "./configure ${CONFIG_OPTS}"
./configure ${CONFIG_OPTS}
echo "::endgroup::"
echo "::group::make"
# make is here to preserve environment variables
make
echo "::endgroup::"
echo "::group::make install"
make install
echo "::endgroup::"
- name: cross-platform-action on ${{ matrix.cross_platform_os }} ${{ matrix.cross_platform_version }}
if: ${{ matrix.with_cross_platform_action == 'yes' }}
uses: cross-platform-actions/action@v1.0.0
env:
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
with:
environment_variables: CROSS_PLATFORM_OS
operating_system: ${{ matrix.cross_platform_os }}
architecture: ${{ matrix.cross_platform_arch }}
version: ${{ matrix.cross_platform_version }}
shell: bash
memory: 4G
cpu_count: 2
run: |
set -e -x
if test "$CROSS_PLATFORM_OS" = "freebsd"; then sudo pkg install -y openssl libevent expat; fi
if test "$CROSS_PLATFORM_OS" = "openbsd"; then sudo pkg_add libevent; fi
if test "$CROSS_PLATFORM_OS" = "netbsd"; then sudo pkgin -y install libevent; fi
echo "::group::configure"
./configure ${{ matrix.cross_platform_config }}
echo "::endgroup::"
echo "::group::make"
make
echo "::endgroup::"
echo "::group::make test"
make test
echo "::endgroup::"
- name: install libevent
if: ${{ matrix.install_libevent == 'yes' }}
run: sudo apt-get install libevent-dev
- name: install expat
if: ${{ matrix.install_expat == 'yes' }}
run: brew install expat
- name: configure
if: ${{ matrix.config != 'no' }}
run: ./configure ${{ matrix.config }}
- name: make
if: ${{ matrix.make != 'no' }}
run: make
- name: make test
if: ${{ matrix.make_test == 'yes' }}
run: make test
- name: clang-analysis
if: ${{ matrix.clang_analysis == 'yes' }}
run: (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
-23
View File
@@ -1,23 +0,0 @@
name: ci
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: configure
run: ./configure --enable-debug
- name: make
run: make
- name: make test
run: make test
+1 -24
View File
@@ -1,19 +1,13 @@
*.lo
*.o
/.libs/
/.source
/Makefile
/autom4te.cache/
/config.h
/config.h.in~
/config.log
/config.status
/dnstap/dnstap_config.h
/dnscrypt/dnscrypt_config.h
/util/configlexer.c
/util/configparser.c
/util/configparser.h
/clubsyms.def
/doc/example.conf
/doc/libunbound.3
/doc/unbound-anchor.8
@@ -24,7 +18,6 @@
/doc/unbound.conf.5
/libtool
/libunbound.la
/_unbound.la
/smallapp/unbound-control-setup.sh
/unbound
/unbound-anchor
@@ -35,31 +28,15 @@
/unbound.h
/asynclook
/delayer
/dohclient
/doqclient
/lock-verify
/memstats
/perf
/petal
/pktview
/readzone
/streamtcp
/unbound-dnstap-socket
/testbound
/unittest
/contrib/libunbound.pc
/contrib/unbound.service
/contrib/unbound.socket
/contrib/unbound_portable.service
/dnstap/dnstap.pb-c.c
/dnstap/dnstap.pb-c.h
/libunbound/python/libunbound_wrap.c
/libunbound/python/unbound.py
/pythonmod/interface.h
/pythonmod/unboundmodule.py
/testdata/result.*
/testdata/.done-*
/testdata/.skip-*
/testdata/.perfstats.txt
/doc/html
/doc/xml
-380
View File
@@ -1,380 +0,0 @@
language: c
git:
depth: 5
addons:
apt:
packages:
- libssl-dev
- libevent-dev
- libexpat-dev
- clang
homebrew:
packages:
- openssl
- libevent
- expat
# homebrew update takes 20min or hangs, so disable update
#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, clang-analysis
compiler: clang
arch: amd64
env:
- CONFIG_OPTS="--enable-debug --disable-flto"
- TEST_ANALYZER=yes
- os: osx
osx_image: xcode12.2
name: Clang on OS X, Amd64, clang-analysis
compiler: clang
arch: amd64
env:
- TEST_OSX=yes
- CONFIG_OPTS="--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl --with-libexpat=/usr/local/opt/expat"
- TEST_ANALYZER=yes
- HOMEBREW_NO_AUTO_UPDATE=1
- 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
osx_image: xcode12.2
name: Libevent, Clang on OS X, Amd64
compiler: clang
arch: amd64
env:
- TEST_OSX=yes
- TEST_LIBEVENT=yes
- CONFIG_OPTS="--disable-flto --with-ssl=/usr/local/opt/openssl --with-libevent=/usr/local/opt/libevent --with-libexpat=/usr/local/opt/expat"
- HOMEBREW_NO_AUTO_UPDATE=1
- 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: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- os: osx
osx_image: xcode12.2
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"
- HOMEBREW_NO_AUTO_UPDATE=1
- 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: osx
name: Apple iPhone on iOS, armv7
- os: osx
name: Apple iPhone on iOS, arm64
- os: osx
name: Apple TV on iOS, arm64
- os: osx
name: Apple Watch on iOS, armv7
- os: osx
name: iPhoneSimulator on OS X, i386
- os: osx
name: iPhoneSimulator on OS X, x86_64
- os: osx
name: AppleTVSimulator on OS X, x86_64
- os: osx
name: WatchSimulator on OS X, i386
- 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:
- |
export MAKE_TEST="yes"
if [ "$TEST_UBSAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover=all"
elif [ "$TEST_ASAN" = "yes" ]; then
export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
fi
- |
if [ "$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
export CONFIG_OPTS="\
--build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST \
--prefix=$IOS_PREFIX \
--with-ssl=$IOS_PREFIX --disable-gost \
--with-libexpat=$IOS_PREFIX "
echo CONFIG_OPTS ${CONFIG_OPTS}
export MAKE_TEST=no
export TEST_INSTALL=yes
fi
- |
if [ "$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
export CONFIG_OPTS="\
--build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST \
--prefix=$ANDROID_PREFIX \
--with-ssl=$ANDROID_PREFIX --disable-gost \
--with-libexpat=$ANDROID_PREFIX "
echo CONFIG_OPTS ${CONFIG_OPTS}
export MAKE_TEST=no
export TEST_INSTALL=yes
fi
- ./configure ${CONFIG_OPTS}
- make -j 2
- |
if [ "$MAKE_TEST" = "yes" ]; then
make test
fi
- |
if [ "$TEST_INSTALL" = "yes" ]; then
make install
fi
- |
if [ "$TEST_ANALYZER" = "yes" ]; then
(cd testdata/clang-analysis.tdir; bash clang-analysis.test)
fi
+501 -934
View File
File diff suppressed because it is too large Load Diff
-278
View File
@@ -1,278 +0,0 @@
# 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 receives 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.
-45
View File
@@ -1,45 +0,0 @@
# Unbound
[![Github Build Status](https://github.com/NLnetLabs/unbound/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/NLnetLabs/unbound/actions)
[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest)
[![Mastodon Follow](https://img.shields.io/mastodon/follow/114692612288811644?domain=social.nlnetlabs.nl&style=social)](https://social.nlnetlabs.nl/@nlnetlabs)
Unbound is a validating, recursive, caching DNS resolver. It is designed to be
fast and lean and incorporates modern features based on open standards. If you
have any feedback, we would love to hear from you. Dont hesitate to
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
or post a message on our [community forum](https://community.nlnetlabs.nl/).
You can learn more about Unbound by reading our
[documentation](https://unbound.docs.nlnetlabs.nl/).
## Compiling
Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
installed.
If building from the repository source you also need flex and bison installed.
Unbound can be compiled and installed using:
```
./configure && make && make install
```
You can use libevent if you want. libevent is useful when using many (e.g.,
10000) outgoing ports.
Use the `--with-libevent` configure option to compile Unbound with libevent
support.
If not, the default builtin alternative opens max 256 ports at the same time
and is equally capable and a little faster.
## Unbound configuration
All of Unbound's configuration options are described in the `unbound.conf(5)`
man page, which will be installed and is also available on the Unbound
[documentation page](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html)
for the latest version.
An example configuration file, with minimal documentation, is located in
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
-31
View File
@@ -1,31 +0,0 @@
# Security Policy
## Supported Versions
NLnet Labs adheres to the straightforward, semantic versioning scheme that is
commonly used in the software industry.
Support is provided in respect of the latest release, i.e. releases with the
highest minor and patch version level. We do not backport security fixes to
older (minor) versions. In the event a new major version is released (e.g. from
3.2.18 to 4.0.0), support will also be provided on the latest minor version of
the previous major version (3.2.18) for a period of one year from the release of
the new major version (4.0.0).
In the event that, during this period, a new patch or minor version of the
previous major version is released, then support on these versions will only be
provided for the remainder of the one-year-period.
You can find detailed information on our software support policy here:
https://www.nlnetlabs.nl/support/software-support-policy/
## Reporting a Vulnerability
We take security very seriously. If you have discovered a security vulnerability
in one of our projects and you would like to report it to us, you can send an
encrypted message to our Security Entry Point.
Details are described here:
https://www.nlnetlabs.nl/security-report/
+52 -58
View File
@@ -1,43 +1,39 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
# http://autoconf-archive.cryp.to/ac_pkg_swig.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PKG_SWIG([major.minor.micro], [action-if-found], [action-if-not-found])
# AC_PROG_SWIG([major.minor.micro])
#
# DESCRIPTION
#
# This macro searches for a SWIG installation on your system. If found,
# then SWIG is AC_SUBST'd; if not found, then $SWIG is empty. If SWIG is
# found, then SWIG_LIB is set to the SWIG library path, and AC_SUBST'd.
# This macro searches for a SWIG installation on your system. If found you
# should call SWIG via $(SWIG). You can use the optional first argument to
# check if the version of the available SWIG is greater than or equal to
# the value of the argument. It should have the format: N[.N[.N]] (N is a
# number between 0 and 999. Only the first N is mandatory.)
#
# You can use the optional first argument to check if the version of the
# available SWIG is greater than or equal to the value of the argument. It
# should have the format: N[.N[.N]] (N is a number between 0 and 999. Only
# the first N is mandatory.) If the version argument is given (e.g.
# 1.3.17), AX_PKG_SWIG checks that the swig package is this version number
# or higher.
#
# As usual, action-if-found is executed if SWIG is found, otherwise
# action-if-not-found is executed.
# If the version argument is given (e.g. 1.3.17), AC_PROG_SWIG checks that
# the swig package is this version number or higher.
#
# In configure.in, use as:
#
# AX_PKG_SWIG(1.3.17, [], [ AC_MSG_ERROR([SWIG is required to build..]) ])
# AX_SWIG_ENABLE_CXX
# AX_SWIG_MULTI_MODULE_SUPPORT
# AX_SWIG_PYTHON
# AC_PROG_SWIG(1.3.17)
# SWIG_ENABLE_CXX
# SWIG_MULTI_MODULE_SUPPORT
# SWIG_PYTHON
#
# LICENSE
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
# Copyright (c) 2008 Alan W. Irwin
# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
# Copyright (c) 2008 Andrew Collier
# Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
# Copyright (c) 2018 Reini Urban <rurban@cpan.org>
# Copyright (c) 2021 Vincent Danjean <Vincent.Danjean@ens-lyon.org>
# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -50,7 +46,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -61,21 +57,17 @@
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
# Macro released by the Autoconf Macro Archive. When you make and
# distribute a modified version of the Autoconf Macro, you may extend this
# special exception to the GPL to apply to your modified version as well.
#serial 15
AC_DEFUN([AX_PKG_SWIG],[
# Find path to the "swig" executable.
AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0])
AC_DEFUN([AC_PROG_SWIG],[
AC_PATH_PROG([SWIG],[swig])
if test -z "$SWIG" ; then
m4_ifval([$3],[$3],[:])
elif test -z "$1" ; then
m4_ifval([$2],[$2],[:])
else
AC_MSG_CHECKING([SWIG version])
AC_MSG_WARN([cannot find 'swig' program. You should look at http://www.swig.org])
SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
elif test -n "$1" ; then
AC_MSG_CHECKING([for SWIG version])
[swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`]
AC_MSG_RESULT([$swig_version])
if test -n "$swig_version" ; then
@@ -85,12 +77,12 @@ AC_DEFUN([AX_PKG_SWIG],[
if test -z "$required_major" ; then
[required_major=0]
fi
[required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_minor=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_minor" ; then
[required_minor=0]
fi
[required=`echo $required. | sed 's/[0-9]*[^0-9]//'`]
[required=`echo $required | sed 's/[0-9]*[^0-9]//'`]
[required_patch=`echo $required | sed 's/[^0-9].*//'`]
if test -z "$required_patch" ; then
[required_patch=0]
@@ -111,28 +103,30 @@ AC_DEFUN([AX_PKG_SWIG],[
if test -z "$available_patch" ; then
[available_patch=0]
fi
# Convert the version tuple into a single number for easier comparison.
# Using base 100 should be safe since SWIG internally uses BCD values
# to encode its version number.
required_swig_vernum=`expr $required_major \* 10000 \
\+ $required_minor \* 100 \+ $required_patch`
available_swig_vernum=`expr $available_major \* 10000 \
\+ $available_minor \* 100 \+ $available_patch`
if test $available_swig_vernum -lt $required_swig_vernum; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version.])
SWIG=''
m4_ifval([$3],[$3],[])
[badversion=0]
if test $available_major -lt $required_major ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -lt $required_minor ; then
[badversion=1]
fi
if test $available_major -eq $required_major \
-a $available_minor -eq $required_minor \
-a $available_patch -lt $required_patch ; then
[badversion=1]
fi
if test $badversion -eq 1 ; then
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
else
AC_MSG_CHECKING([for SWIG library])
SWIG_LIB=`$SWIG -swiglib | tr '\r\n' ' '`
AC_MSG_RESULT([$SWIG_LIB])
m4_ifval([$2],[$2],[])
AC_MSG_NOTICE([SWIG executable is '$SWIG'])
SWIG_LIB=`$SWIG -swiglib`
AC_MSG_NOTICE([SWIG library directory is '$SWIG_LIB'])
fi
else
AC_MSG_WARN([cannot determine SWIG version])
SWIG=''
m4_ifval([$3],[$3],[])
SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
fi
fi
AC_SUBST([SWIG_LIB])
Vendored
+4 -4
View File
@@ -1,6 +1,6 @@
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
# Copyright (C) 1996-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9390,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
# Copyright (C) 1997-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
# Copyright (C) 2006-2018 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
+114 -256
View File
@@ -2,29 +2,7 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 51
# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
# a warning for 'unknown attribute' when nonstring is used.
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
# check by ACX_FUNC_MALLOC.
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
# and check for getaddrinfo with only header.
# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
# 2023-05-04 fix to remove unused whitespace.
# 2023-01-26 fix -Wstrict-prototypes.
# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD.
# 2021-08-17 fix sed script in ssldir split handling.
# 2021-08-17 fix for openssl to detect split version, with ssldir_include
# and ssldir_lib output directories.
# 2021-07-30 fix for openssl use of lib64 directory.
# 2021-06-14 fix nonblocking test to use host instead of target for mingw test.
# 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for
# 64bit compatibility.
# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS.
# 2021-01-05 fix defun for aclocal
# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
# Version 34
# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0.
# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0).
# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20
@@ -76,7 +54,6 @@
# ACX_DEPFLAG - find cc dependency flags.
# ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX.
# ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax.
# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax.
# ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax.
# ACX_CHECK_FLTO - see if cc supports -flto and use it if so.
# ACX_LIBTOOL_C_ONLY - create libtool for C only, improved.
@@ -98,7 +75,6 @@
# ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably.
# ACX_FUNC_MALLOC - check malloc, define replacement .
# AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format.
# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring.
# AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused.
# AHX_CONFIG_FSEEKO - define fseeko, ftello fallback.
# AHX_CONFIG_RAND_MAX - define RAND_MAX if needed.
@@ -199,7 +175,7 @@ dnl cache=`echo $1 | sed 'y%.=/+- %___p__%'`
AC_CACHE_VAL(cv_prog_cc_flag_needed_$cache,
[
echo '$2' > conftest.c
echo 'void f(void){}' >>conftest.c
echo 'void f(){}' >>conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS $ERRFLAG -c conftest.c 2>&1`"; then
eval "cv_prog_cc_flag_needed_$cache=no"
else
@@ -245,7 +221,7 @@ dnl DEPFLAG: set to flag that generates dependencies.
AC_DEFUN([ACX_DEPFLAG],
[
AC_MSG_CHECKING([$CC dependency flag])
echo 'void f(void){}' >conftest.c
echo 'void f(){}' >conftest.c
if test "`$CC -MM conftest.c 2>&1`" = "conftest.o: conftest.c"; then
DEPFLAG="-MM"
else
@@ -284,7 +260,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAUL
#include <getopt.h>
#endif
int test(void) {
int test() {
int a;
char **opts = NULL;
struct timeval tv;
@@ -321,7 +297,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAUL
#include <getopt.h>
#endif
int test(void) {
int test() {
int a;
char **opts = NULL;
struct timeval tv;
@@ -347,7 +323,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG,
[
#include <stdbool.h>
#include <ctype.h>
int test(void) {
int test() {
int a = 0;
return a;
}
@@ -357,7 +333,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE,
[
#include <ctype.h>
int test(void) {
int test() {
int a;
a = isascii(32);
return a;
@@ -368,7 +344,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE,
[
#include <netinet/in.h>
int test(void) {
int test() {
struct in6_pktinfo inf;
int a = (int)sizeof(inf);
return a;
@@ -382,7 +358,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_GNU_SOURCE -D_FRSRESGID,
[
#include <unistd.h>
int test(void) {
int test() {
int a = setresgid(0,0,0);
a = setresuid(0,0,0);
return a;
@@ -397,7 +373,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D_POSIX_C_SOURCE=200112,
#endif
#include <netdb.h>
int test(void) {
int test() {
int a = 0;
char *t;
time_t time = 0;
@@ -425,7 +401,7 @@ ACX_CHECK_COMPILER_FLAG_NEEDED(-D__EXTENSIONS__,
#include <getopt.h>
#endif
int test(void) {
int test() {
int a;
char **opts = NULL;
struct timeval tv;
@@ -470,12 +446,15 @@ AC_DEFUN([ACX_CHECK_FORMAT_ATTRIBUTE],
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
AC_CACHE_VAL(ac_cv_c_format_attribute,
[ac_cv_c_format_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
AC_TRY_COMPILE(
[#include <stdio.h>
void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
]], [[
], [
f ("%s", "str");
]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
],
[ac_cv_c_format_attribute="yes"],
[ac_cv_c_format_attribute="no"])
])
AC_MSG_RESULT($ac_cv_c_format_attribute)
@@ -487,7 +466,7 @@ fi
dnl Setup ATTR_FORMAT config.h parts.
dnl make sure you call ACX_CHECK_FORMAT_ATTRIBUTE also.
AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
[
[
#ifdef HAVE_ATTR_FORMAT
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
@@ -497,18 +476,21 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE],
])
dnl Check how to mark function arguments as unused.
dnl result in HAVE_ATTR_UNUSED.
dnl result in HAVE_ATTR_UNUSED.
dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
AC_CACHE_VAL(ac_cv_c_unused_attribute,
[ac_cv_c_unused_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
AC_TRY_COMPILE(
[#include <stdio.h>
void f (char *u __attribute__((unused)));
]], [[
], [
f ("x");
]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
],
[ac_cv_c_unused_attribute="yes"],
[ac_cv_c_unused_attribute="no"])
])
dnl Setup ATTR_UNUSED config.h parts.
@@ -532,49 +514,6 @@ if test $ac_cv_c_unused_attribute = yes; then
fi
])dnl
dnl Check how to mark function arguments as nonstring.
dnl result in HAVE_ATTR_NONSTRING.
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
[AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([ACX_CHECK_ERROR_FLAGS])
BAKCFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $ERRFLAG"
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
[ac_cv_c_nonstring_attribute=no
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
struct test {
char __attribute__((nonstring)) s[1];
};
]], [[
struct test t = { "1" };
(void) t;
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
CFLAGS="$BAKCFLAGS"
])
dnl Setup ATTR_NONSTRING config.h parts.
dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also.
AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE],
[
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
])
AC_MSG_RESULT($ac_cv_c_nonstring_attribute)
if test $ac_cv_c_nonstring_attribute = yes; then
AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute])
fi
])dnl
dnl Pre-fun for ACX_LIBTOOL_C_ONLY
AC_DEFUN([ACX_LIBTOOL_C_PRE], [
# skip these tests, we do not need them.
@@ -608,7 +547,7 @@ dnl as a requirement so that is gets called before LIBTOOL
dnl because libtools 'AC_REQUIRE' names are right after this one, before
dnl this function contents.
AC_REQUIRE([ACX_LIBTOOL_C_PRE])
LT_INIT
AC_PROG_LIBTOOL
])
dnl Detect if u_char type is defined, otherwise define it.
@@ -706,30 +645,6 @@ AC_DEFUN([ACX_SSL_CHECKS], [
withval=$1
if test x_$withval != x_no; then
AC_MSG_CHECKING(for SSL)
if test -n "$withval"; then
dnl look for openssl install with different version, eg.
dnl in /usr/include/openssl11/openssl/ssl.h
dnl and /usr/lib64/openssl11/libssl.so
dnl with the --with-ssl=/usr/include/openssl11
if test ! -f "$withval/include/openssl/ssl.h" -a -f "$withval/openssl/ssl.h"; then
ssldir="$withval"
found_ssl="yes"
withval=""
ssldir_include="$ssldir"
dnl find the libdir
ssldir_lib=`echo $ssldir | sed -e 's/include/lib/'`
if test -f "$ssldir_lib/libssl.a" -o -f "$ssldir_lib/libssl.so"; then
: # found here
else
ssldir_lib=`echo $ssldir | sed -e 's/include/lib64/'`
if test -f "$ssldir_lib/libssl.a" -o -f "$ssldir_lib/libssl.so"; then
: # found here
else
AC_MSG_ERROR([Could not find openssl lib file, $ssldir_lib/libssl.[so,a], pass like "/usr/local" or "/usr/include/openssl11"])
fi
fi
fi
fi
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr"
fi
@@ -737,12 +652,12 @@ AC_DEFUN([ACX_SSL_CHECKS], [
ssldir="$dir"
if test -f "$dir/include/openssl/ssl.h"; then
found_ssl="yes"
ssldir_include="$ssldir/include"
if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then
ssldir_lib="$ssldir/lib64"
else
ssldir_lib="$ssldir/lib"
fi
AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.])
dnl assume /usr/include is already in the include-path.
if test "$ssldir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$ssldir/include"
LIBSSL_CPPFLAGS="$LIBSSL_CPPFLAGS -I$ssldir/include"
fi
break;
fi
done
@@ -750,28 +665,25 @@ AC_DEFUN([ACX_SSL_CHECKS], [
AC_MSG_ERROR(Cannot find the SSL libraries in $withval)
else
AC_MSG_RESULT(found in $ssldir)
AC_DEFINE_UNQUOTED([HAVE_SSL], [], [Define if you have the SSL libraries installed.])
HAVE_SSL=yes
dnl assume /usr is already in the include, lib and dynlib paths.
if test "$ssldir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$ssldir_include"
LIBSSL_CPPFLAGS="$LIBSSL_CPPFLAGS -I$ssldir_include"
LDFLAGS="$LDFLAGS -L$ssldir_lib"
LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir_lib"
ACX_RUNTIME_PATH_ADD([$ssldir_lib])
fi
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
dnl assume /usr is already in the lib and dynlib paths.
if test "$ssldir" != "/usr" -a "$ssldir" != ""; then
LDFLAGS="$LDFLAGS -L$ssldir/lib"
LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
ACX_RUNTIME_PATH_ADD([$ssldir/lib])
fi
AC_MSG_CHECKING([for HMAC_Update in -lcrypto])
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_TRY_LINK(, [
int HMAC_Update(void);
(void)HMAC_Update();
], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
], [
AC_MSG_RESULT(no)
# check if -lwsock32 or -lgdi32 are needed.
BAKLIBS="$LIBS"
@@ -779,79 +691,46 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBS="$LIBS -lgdi32 -lws2_32"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
int EVP_sha256(void);
(void)EVP_sha256();
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
])
])
LIBS="$LIBS -ldl"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
LIBS="$LIBS -ldl -pthread"
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
])
])
])
])
])
fi
@@ -865,13 +744,14 @@ AC_CHECK_HEADERS([openssl/rand.h],,, [AC_INCLUDES_DEFAULT])
dnl Check for SSL, where SSL is mandatory
dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found
dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
dnl Checks main header files of SSL.
dnl
AC_DEFUN([ACX_WITH_SSL],
[
AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr or specify like /usr/include/openssl11)]),[
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[
withval="yes"
])
@@ -888,8 +768,9 @@ dnl Checks main header files of SSL.
dnl
AC_DEFUN([ACX_WITH_SSL_OPTIONAL],
[
AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr or specify like /usr/include/openssl11)]),[
AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
[enable SSL (will check /usr/local/ssl
/usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
],[
withval="yes"
])
@@ -922,7 +803,7 @@ dnl try to see if an additional _LARGEFILE_SOURCE 1 is needed to get fseeko
ACX_CHECK_COMPILER_FLAG_NEEDED(-D_LARGEFILE_SOURCE=1,
[
#include <stdio.h>
int test(void) {
int test() {
int a = fseeko(stdin, 0, 0);
return a;
}
@@ -947,7 +828,7 @@ char* (*f) () = getaddrinfo;
#ifdef __cplusplus
}
#endif
int main(void) {
int main() {
;
return 0;
}
@@ -958,7 +839,7 @@ dnl see if on windows
if test "$ac_cv_header_windows_h" = "yes"; then
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
USE_WINSOCK="1"
if echo "$LIBS" | grep 'lws2_32' >/dev/null; then
if echo $LIBS | grep 'lws2_32' >/dev/null; then
:
else
LIBS="$LIBS -lws2_32"
@@ -966,24 +847,6 @@ if test "$ac_cv_header_windows_h" = "yes"; then
fi
],
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
dnl perhaps getaddrinfo needs only the include
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
[
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
],
[
(void)getaddrinfo(NULL, NULL, NULL, NULL);
]
)],
[
ac_cv_func_getaddrinfo="yes"
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
USE_WINSOCK="1"
],
ORIGLIBS="$LIBS"
LIBS="$LIBS -lws2_32"
AC_LINK_IFELSE(
@@ -1008,7 +871,6 @@ ac_cv_func_getaddrinfo="no"
LIBS="$ORIGLIBS"
])
)
)
AC_MSG_RESULT($ac_cv_func_getaddrinfo)
if test $ac_cv_func_getaddrinfo = yes; then
@@ -1030,8 +892,8 @@ cache=`echo $1 | sed 'y%.=/+-%___p_%'`
AC_CACHE_VAL(cv_cc_deprecated_$cache,
[
echo '$3' >conftest.c
echo 'void f(void){ $2 }' >>conftest.c
if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
echo 'void f(){ $2 }' >>conftest.c
if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then
eval "cv_cc_deprecated_$cache=no"
else
eval "cv_cc_deprecated_$cache=yes"
@@ -1057,7 +919,7 @@ dnl a nonblocking socket do not work, a new call to select is necessary.
AC_DEFUN([ACX_CHECK_NONBLOCKING_BROKEN],
[
AC_MSG_CHECKING([if nonblocking sockets work])
if echo $host | grep mingw >/dev/null; then
if echo $target | grep mingw32 >/dev/null; then
AC_MSG_RESULT([no (windows)])
AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).])
else
@@ -1071,9 +933,6 @@ AC_LANG_SOURCE([[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
@@ -1202,7 +1061,7 @@ dnl defines MKDIR_HAS_ONE_ARG
AC_DEFUN([ACX_MKDIR_ONE_ARG],
[
AC_MSG_CHECKING([whether mkdir has one arg])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
AC_TRY_COMPILE([
#include <stdio.h>
#include <unistd.h>
#ifdef HAVE_WINSOCK2_H
@@ -1211,12 +1070,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
]], [[
], [
(void)mkdir("directory");
]])],[AC_MSG_RESULT(yes)
],
AC_MSG_RESULT(yes)
AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
],[AC_MSG_RESULT(no)
])
,
AC_MSG_RESULT(no)
)
])dnl end of ACX_MKDIR_ONE_ARG
dnl Check for ioctlsocket function. works on mingw32 too.
@@ -1240,9 +1101,8 @@ dnl detect malloc and provide malloc compat prototype.
dnl $1: unique name for compat code
AC_DEFUN([ACX_FUNC_MALLOC],
[
AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull],
[
AC_RUN_IFELSE([AC_LANG_PROGRAM(
AC_MSG_CHECKING([for GNU libc compatible malloc])
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[#if defined STDC_HEADERS || defined HAVE_STDLIB_H
#include <stdlib.h>
#else
@@ -1250,16 +1110,14 @@ char *malloc ();
#endif
]], [ if(malloc(0) != 0) return 1;])
],
[ac_cv_func_malloc_0_nonnull=no],
[ac_cv_func_malloc_0_nonnull=yes],
[ac_cv_func_malloc_0_nonnull="no (crosscompile)"])
])
AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes],
[AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])
])
[AC_MSG_RESULT([no])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ,
[AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])],
[AC_MSG_RESULT([no (crosscompile)])
AC_LIBOBJ(malloc)
AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] )
])
dnl Define fallback for fseeko and ftello if needed.
@@ -1427,7 +1285,7 @@ AC_DEFUN([AHX_CONFIG_W32_FD_SET_T],
#ifdef HAVE_WINSOCK2_H
#define FD_SET_T (u_int)
#else
#define FD_SET_T
#define FD_SET_T
#endif
])
@@ -1465,7 +1323,7 @@ dnl $3: define value, 1
AC_DEFUN([AHX_CONFIG_FLAG_OMITTED],
[#if defined($1) && !defined($2)
#define $2 $3
[#]endif])
[#]endif ])
dnl Wrapper for AHX_CONFIG_FLAG_OMITTED for -D style flags
dnl $1: the -DNAME or -DNAME=value string.
+20 -77
View File
@@ -9,7 +9,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
if test -z "$PYTHON"; then
AC_MSG_ERROR([Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version.])
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
PYTHON_VERSION=""
fi
@@ -17,75 +17,28 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
PYTHON_VERSION=`$PYTHON -c "import sys; \
print(sys.version.split()[[0]])"`
fi
# calculate the version number components.
[
v="$PYTHON_VERSION"
PYTHON_VERSION_MAJOR=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_MAJOR"; then PYTHON_VERSION_MAJOR="0"; fi
v=`echo $v | sed -e 's/^[0-9]*$//' -e 's/[0-9]*[^0-9]//'`
PYTHON_VERSION_MINOR=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_MINOR"; then PYTHON_VERSION_MINOR="0"; fi
v=`echo $v | sed -e 's/^[0-9]*$//' -e 's/[0-9]*[^0-9]//'`
PYTHON_VERSION_PATCH=`echo $v | sed 's/[^0-9].*//'`
if test -z "$PYTHON_VERSION_PATCH"; then PYTHON_VERSION_PATCH="0"; fi
]
# For some systems, sysconfig exists, but has the wrong paths,
# on Debian 10, for python 2.7 and 3.7. So, we check the version,
# and for older versions try distutils.sysconfig first. For newer
# versions>=3.10, where distutils.sysconfig is deprecated, use
# sysconfig first and then attempt the other one.
py_distutils_first="no"
if test $PYTHON_VERSION_MAJOR -lt 3; then
py_distutils_first="yes"
fi
if test $PYTHON_VERSION_MAJOR -eq 3 -a $PYTHON_VERSION_MINOR -lt 10; then
py_distutils_first="yes"
fi
# Check if you have the first module
if test "$py_distutils_first" = "yes"; then m="distutils"; else m="sysconfig"; fi
sysconfig_module=""
AC_MSG_CHECKING([for the $m Python module])
if ac_modulecheck_result1=`$PYTHON -c "import $m" 2>&1`; then
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
AC_MSG_RESULT([yes])
sysconfig_module="$m"
else
else
AC_MSG_RESULT([no])
fi
# if not found, try the other one.
if test -z "$sysconfig_module"; then
if test "$py_distutils_first" = "yes"; then m2="sysconfig"; else m2="distutils"; fi
AC_MSG_CHECKING([for the $m2 Python module])
if ac_modulecheck_result2=`$PYTHON -c "import $m2" 2>&1`; then
AC_MSG_RESULT([yes])
sysconfig_module="$m2"
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "$m", or "$m2".
Please check your Python installation. The errors are:
$m
$ac_modulecheck_result1
$m2
$ac_modulecheck_result2])
PYTHON_VERSION=""
fi
fi
if test "$sysconfig_module" = "distutils"; then sysconfig_module="distutils.sysconfig"; fi
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
PYTHON_VERSION=""
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
if test "$sysconfig_module" = "sysconfig"; then
python_path=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("include"));'`
else
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
fi
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
if test -n "${python_path}"; then
python_path="-I$python_path"
fi
@@ -99,29 +52,19 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
#
AC_MSG_CHECKING([for Python library path])
if test -z "$PYTHON_LDFLAGS"; then
PYTHON_LDFLAGS=`$PYTHON -c "from $sysconfig_module import *; \
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
fi
AC_MSG_RESULT([$PYTHON_LDFLAGS])
AC_SUBST([PYTHON_LDFLAGS])
if test -z "$PYTHON_LIBDIR"; then
PYTHON_LIBDIR=`$PYTHON -c "from $sysconfig_module import *; \
print(get_config_var('LIBDIR'));"`
fi
#
# Check for site packages
#
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
if test "$sysconfig_module" = "sysconfig"; then
PYTHON_SITE_PKG=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("platlib"));'`
else
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
fi
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])
@@ -137,11 +80,11 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
LIBS="$LIBS $PYTHON_LDFLAGS"
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
AC_TRY_LINK([
#include <Python.h>
]],[[
],[
Py_Initialize();
]])],[pythonexists=yes],[pythonexists=no])
],[pythonexists=yes],[pythonexists=no])
AC_MSG_RESULT([$pythonexists])
-70
View File
@@ -1,70 +0,0 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_build_date_epoch.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BUILD_DATE_EPOCH(VARIABLE[, FORMAT[, ACTION-IF-FAIL]])
#
# DESCRIPTION
#
# Sets VARIABLE to a string representing the current time. It is
# formatted according to FORMAT if specified, otherwise it is formatted as
# the number of seconds (excluding leap seconds) since the UNIX epoch (01
# Jan 1970 00:00:00 UTC).
#
# If the SOURCE_DATE_EPOCH environment variable is set, it uses the value
# of that variable instead of the current time. See
# https://reproducible-builds.org/specs/source-date-epoch). If
# SOURCE_DATE_EPOCH is set but cannot be properly interpreted as a UNIX
# timestamp, then execute ACTION-IF-FAIL if specified, otherwise error.
#
# VARIABLE is AC_SUBST-ed.
#
# LICENSE
#
# Copyright (c) 2016 Eric Bavier <bavier@member.fsf.org>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 2
AC_DEFUN([AX_BUILD_DATE_EPOCH],
[dnl
AC_MSG_CHECKING([for build time])
ax_date_fmt="m4_default($2,%s)"
AS_IF([test x"$SOURCE_DATE_EPOCH" = x],
[$1=`date "+$ax_date_fmt"`],
[ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \
|| date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null`
AS_IF([test x"$ax_build_date" = x],
[m4_ifval([$3],
[$3],
[AC_MSG_ERROR([malformed SOURCE_DATE_EPOCH])])],
[$1=$ax_build_date])])
AC_MSG_RESULT([$$1])
])dnl AX_BUILD_DATE_EPOCH
+127 -332
View File
@@ -1,5 +1,5 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
@@ -14,28 +14,24 @@
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
# needed for multi-threaded programs (defaults to the value of CC
# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
# special cc_r/CC_r compiler alias.)
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also to link with them as well. For example, you might link with
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threaded programs, you may wish to use these
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
# CXX="$PTHREAD_CXX"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
@@ -59,7 +55,6 @@
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
@@ -72,7 +67,7 @@
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program. If not, see <https://www.gnu.org/licenses/>.
# with this program. If not, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
@@ -87,41 +82,35 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 32
#serial 21
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_PROG_SED])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on Tru64 or Sequent).
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
ax_pthread_save_CC="$CC"
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = "xno"; then
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
CC="$ax_pthread_save_CC"
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
@@ -129,14 +118,12 @@ fi
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items with a "," contain both
# C compiler flags (before ",") and linker flags (after ","). Other items
# starting with a "-" are C compiler flags, and remaining items are
# library names, except for "none" which indicates that we try without
# any flags at all, and "pthread-config" which is a program returning
# the flags for the Pth emulation library.
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
@@ -145,178 +132,82 @@ ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
# (Note: HP C rejects this with "bad form for `-t' option")
# -pthreads: Solaris/gcc (Note: HP C also rejects)
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads and
# -D_REENTRANT too), HP C (must be checked before -lpthread, which
# is present but should not be used directly; and before -mthreads,
# because the compiler interprets this as "-mt" + "-hreads")
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case $host_os in
freebsd*)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
ax_pthread_flags="-kthread lthread $ax_pthread_flags"
;;
hpux*)
# From the cc(1) man page: "[-mt] Sets various -D flags to enable
# multi-threading and also sets -lpthread."
ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
;;
openedition*)
# IBM z/OS requires a feature-test macro to be defined in order to
# enable POSIX threads at all, so give the user a hint if this is
# not set. (We don't define these ourselves, as they can affect
# other portions of the system API in unpredictable ways.)
AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
[
# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
AX_PTHREAD_ZOS_MISSING
# endif
],
[AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
;;
case ${host_os} in
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (N.B.: The stubs are missing
# pthread_cleanup_push, or rather a function called by this macro,
# so we could check for that, but who knows whether they'll stub
# that too in a future libc.) So we'll check first for the
# standard Solaris way of linking pthreads (-mt -lpthread).
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
;;
esac
# Are we compiling with Clang?
# Clang doesn't consider unrecognized options an error unless we specify
# -Werror. We throw in some extra Clang-specific options to ensure that
# this doesn't happen for GCC, which also accepts -Werror.
AC_CACHE_CHECK([whether $CC is Clang],
[ax_cv_PTHREAD_CLANG],
[ax_cv_PTHREAD_CLANG=no
# Note that Autoconf sets GCC=yes for Clang as well as GCC
if test "x$GCC" = "xyes"; then
AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
[/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
# if defined(__clang__) && defined(__llvm__)
AX_PTHREAD_CC_IS_CLANG
# endif
],
[ax_cv_PTHREAD_CLANG=yes])
fi
])
ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
save_CFLAGS="$CFLAGS"
ax_pthread_extra_flags="-Werror"
CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
[AC_MSG_RESULT([yes])],
[ax_pthread_extra_flags=
AC_MSG_RESULT([no])])
CFLAGS="$save_CFLAGS"
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
# Note that for GCC and Clang -pthread generally implies -lpthread,
# except when -nostdlib is passed.
# This is problematic using libtool to build C++ shared libraries with pthread:
# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
# To solve this, first try -pthread together with -lpthread for GCC
AS_IF([test "x$GCC" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
AS_IF([test "x$ax_pthread_clang" = "xyes"],
[ax_pthread_flags="-pthread,-lpthread -pthread"])
# The presence of a feature test macro requesting re-entrant function
# definitions is, on some systems, a strong hint that pthreads support is
# correctly enabled
case $host_os in
solaris*)
# Solaris 11.4 introduced XPG7 support and did away with the need for
# _REENTRANT.
AC_EGREP_CPP([AX_PTHREAD_SOLARIS__REENTRANT],
[
# undef _XOPEN_SOURCE
# include <sys/feature_tests.h>
# if _XOPEN_VERSION < 700
AX_PTHREAD_SOLARIS__REENTRANT
# endif
],
[ax_pthread_check_macro="_REENTRANT"],
[ax_pthread_check_macro="--"])
;;
darwin* | hpux* | linux* | osf*)
ax_pthread_check_macro="_REENTRANT"
;;
aix*)
ax_pthread_check_macro="_THREAD_SAFE"
;;
*)
ax_pthread_check_macro="--"
;;
esac
AS_IF([test "x$ax_pthread_check_macro" = "x--"],
[ax_pthread_check_cond=0],
[ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
if test "x$ax_pthread_ok" = "xno"; then
for ax_pthread_try_flag in $ax_pthread_flags; do
case $ax_pthread_try_flag in
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
*,*)
PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
PTHREAD_CFLAGS="$ax_pthread_try_flag"
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
PTHREAD_LIBS="-l$ax_pthread_try_flag"
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@@ -327,18 +218,8 @@ for ax_pthread_try_flag in $ax_pthread_flags; do
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
# if $ax_pthread_check_cond
# error "$ax_pthread_check_macro must be defined"
# endif
static void *some_global = NULL;
static void routine(void *a)
{
/* To avoid any unused-parameter or
unused-but-set-parameter warning. */
some_global = a;
}
static void routine(void *a) { *((int*)a) = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
@@ -346,187 +227,101 @@ for ax_pthread_try_flag in $ax_pthread_flags; do
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
[ax_pthread_ok=yes],
[])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT([$ax_pthread_ok])
AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Clang needs special handling, because older versions handle the -pthread
# option in a rather... idiosyncratic way
if test "x$ax_pthread_clang" = "xyes"; then
# Clang takes -pthread; it has never supported any other flag
# (Note 1: This will need to be revisited if a system that Clang
# supports has POSIX threads in a separate library. This tends not
# to be the way of modern systems, but it's conceivable.)
# (Note 2: On some systems, notably Darwin, -pthread is not needed
# to get POSIX threads support; the API is always present and
# active. We could reasonably leave PTHREAD_CFLAGS empty. But
# -pthread does define _REENTRANT, and while the Darwin headers
# ignore this macro, third-party headers might not.)
# However, older versions of Clang make a point of warning the user
# that, in an invocation where only linking and no compilation is
# taking place, the -pthread option has no effect ("argument unused
# during compilation"). They expect -pthread to be passed in only
# when source code is being compiled.
#
# Problem is, this is at odds with the way Automake and most other
# C build frameworks function, which is that the same flags used in
# compilation (CFLAGS) are also used in linking. Many systems
# supported by AX_PTHREAD require exactly this for POSIX threads
# support, and in fact it is often not straightforward to specify a
# flag that is used only in the compilation phase and not in
# linking. Such a scenario is extremely rare in practice.
#
# Even though use of the -pthread flag in linking would only print
# a warning, this can be a nuisance for well-run software projects
# that build with -Werror. So if the active version of Clang has
# this misfeature, we search for an option to squash it.
AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
[ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
# Create an alternate version of $ac_link that compiles and
# links in two steps (.c -> .o, .o -> exe) instead of one
# (.c -> exe), because the warning occurs only in the second
# step
ax_pthread_save_ac_link="$ac_link"
ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
ax_pthread_save_CFLAGS="$CFLAGS"
for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
ac_link="$ax_pthread_save_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[ac_link="$ax_pthread_2step_ac_link"
AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
[break])
])
done
ac_link="$ax_pthread_save_ac_link"
CFLAGS="$ax_pthread_save_CFLAGS"
AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
])
case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
no | unknown) ;;
*) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
esac
fi # $ax_pthread_clang = yes
# Various other checks:
if test "x$ax_pthread_ok" = "xyes"; then
ax_pthread_save_CFLAGS="$CFLAGS"
ax_pthread_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_CACHE_CHECK([for joinable pthread attribute],
[ax_cv_PTHREAD_JOINABLE_ATTR],
[ax_cv_PTHREAD_JOINABLE_ATTR=unknown
for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $ax_pthread_attr; return attr /* ; */])],
[ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
[])
done
])
AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
test "x$ax_pthread_joinable_attr_defined" != "xyes"],
[AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
[$ax_cv_PTHREAD_JOINABLE_ATTR],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
ax_pthread_joinable_attr_defined=yes
])
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT([$attr_name])
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_CACHE_CHECK([whether more special flags are required for pthreads],
[ax_cv_PTHREAD_SPECIAL_FLAGS],
[ax_cv_PTHREAD_SPECIAL_FLAGS=no
case $host_os in
solaris*)
ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
;;
esac
])
AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
test "x$ax_pthread_special_flags_added" != "xyes"],
[PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
ax_pthread_special_flags_added=yes])
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case ${host_os} in
aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
osf* | hpux*) flag="-D_REENTRANT";;
solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
# TODO: What about Clang on Solaris?
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT([$flag])
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT],
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;
return i;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
[ax_cv_PTHREAD_PRIO_INHERIT], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
test "x$ax_pthread_prio_inherit_defined" != "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
ax_pthread_prio_inherit_defined=yes
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
CFLAGS="$ax_pthread_save_CFLAGS"
LIBS="$ax_pthread_save_LIBS"
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: compile with *_r variant
if test "x$GCC" != "xyes"; then
if test "x$GCC" != xyes; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[
AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
],
[
AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
]
)
])
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
AC_SUBST([PTHREAD_CXX])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test "x$ax_pthread_ok" = "xyes"; then
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
+82 -335
View File
@@ -47,12 +47,9 @@
#include "util/regional.h"
#include "util/net_help.h"
#include "util/config_file.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "services/cache/dns.h"
#include "services/mesh.h"
#include "services/modstack.h"
#include "validator/val_neg.h"
#include "validator/val_secalgo.h"
#include "iterator/iter_utils.h"
@@ -67,26 +64,13 @@
#ifdef HAVE_SYS_ENDIAN_H
# include <sys/endian.h>
#endif
#ifndef HAVE_HTOBE64
# ifdef HAVE_LIBKERN_OSBYTEORDER_H
/* In practice this is specific to MacOS X. We assume it doesn't have
* htobe64/be64toh but has alternatives with a different name. */
# include <libkern/OSByteOrder.h>
# define htobe64(x) OSSwapHostToBigInt64(x)
# define be64toh(x) OSSwapBigToHostInt64(x)
# else
/* not OSX */
/* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
# if __BIG_ENDIAN__
# define be64toh(n) (n)
# define htobe64(n) (n)
# else
# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
# endif /* _ENDIAN */
# endif /* HAVE_LIBKERN_OSBYTEORDER_H */
#endif /* HAVE_BE64TOH */
#ifdef HAVE_LIBKERN_OSBYTEORDER_H
/* In practice this is specific to MacOS X. We assume it doesn't have
* htobe64/be64toh but has alternatives with a different name. */
# include <libkern/OSByteOrder.h>
# define htobe64(x) OSSwapHostToBigInt64(x)
# define be64toh(x) OSSwapBigToHostInt64(x)
#endif
/** the unit test testframe for cachedb, its module state contains
* a cache for a couple queries (in memory). */
@@ -105,6 +89,7 @@ static int
testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
{
struct testframe_moddata* d;
(void)env;
verbose(VERB_ALGO, "testframe_init");
d = (struct testframe_moddata*)calloc(1,
sizeof(struct testframe_moddata));
@@ -113,15 +98,6 @@ testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
log_err("out of memory");
return 0;
}
/* Register an EDNS option (65534) to bypass the worker cache lookup
* for testing */
if(!edns_register_option(LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST,
1 /* bypass cache */,
0 /* no aggregation */, env)) {
log_err("testframe_init, could not register test opcode");
free(d);
return 0;
}
lock_basic_init(&d->lock);
lock_protect(&d->lock, d, sizeof(*d));
return 1;
@@ -171,7 +147,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, time_t ATTR_UNUSED(ttl))
char* key, uint8_t* data, size_t data_len)
{
struct testframe_moddata* d = (struct testframe_moddata*)
cachedb_env->backend_data;
@@ -229,8 +205,10 @@ static int
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
{
const char* backend_str = cfg->cachedb_backend;
if(!backend_str || *backend_str==0)
return 1;
/* If unspecified we use the in-memory test DB. */
if(!backend_str)
backend_str = "testframe";
cachedb_env->backend = cachedb_find_backend(backend_str);
if(!cachedb_env->backend) {
log_err("cachedb: cannot find backend name '%s'", backend_str);
@@ -241,7 +219,7 @@ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
return 1;
}
int
int
cachedb_init(struct module_env* env, int id)
{
struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
@@ -253,8 +231,6 @@ cachedb_init(struct module_env* env, int id)
env->modinfo[id] = (void*)cachedb_env;
if(!cachedb_apply_cfg(cachedb_env, env->cfg)) {
log_err("cachedb: could not apply configuration settings.");
free(cachedb_env);
env->modinfo[id] = NULL;
return 0;
}
/* see if a backend is selected */
@@ -263,24 +239,25 @@ cachedb_init(struct module_env* env, int id)
if(!(*cachedb_env->backend->init)(env, cachedb_env)) {
log_err("cachedb: could not init %s backend",
cachedb_env->backend->name);
free(cachedb_env);
env->modinfo[id] = NULL;
return 0;
}
cachedb_env->enabled = 1;
return 1;
}
void
void
cachedb_deinit(struct module_env* env, int id)
{
struct cachedb_env* cachedb_env;
if(!env || !env->modinfo[id])
return;
cachedb_env = (struct cachedb_env*)env->modinfo[id];
/* free contents */
/* TODO */
if(cachedb_env->enabled) {
(*cachedb_env->backend->deinit)(env, cachedb_env);
}
free(cachedb_env);
env->modinfo[id] = NULL;
}
@@ -323,31 +300,31 @@ error_response(struct module_qstate* qstate, int id, int rcode)
/**
* Hash the query name, type, class and dbacess-secret into lookup buffer.
* @param qinfo: query info
* @param env: with env->cfg with secret.
* @param qstate: query state with query info
* and env->cfg with secret.
* @param buf: returned buffer with hash to lookup
* @param len: length of the buffer.
*/
static void
calc_hash(struct query_info* qinfo, struct module_env* env, char* buf,
size_t len)
calc_hash(struct module_qstate* qstate, char* buf, size_t len)
{
uint8_t clear[1024];
size_t clen = 0;
uint8_t hash[CACHEDB_HASHSIZE/8];
const char* hex = "0123456789ABCDEF";
const char* secret = env->cfg->cachedb_secret;
const char* secret = qstate->env->cfg->cachedb_secret ?
qstate->env->cfg->cachedb_secret : "default";
size_t i;
/* copy the hash info into the clear buffer */
if(clen + qinfo->qname_len < sizeof(clear)) {
memmove(clear+clen, qinfo->qname, qinfo->qname_len);
query_dname_tolower(clear+clen);
clen += qinfo->qname_len;
if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
memmove(clear+clen, qstate->qinfo.qname,
qstate->qinfo.qname_len);
clen += qstate->qinfo.qname_len;
}
if(clen + 4 < sizeof(clear)) {
uint16_t t = htons(qinfo->qtype);
uint16_t c = htons(qinfo->qclass);
uint16_t t = htons(qstate->qinfo.qtype);
uint16_t c = htons(qstate->qinfo.qclass);
memmove(clear+clen, &t, 2);
memmove(clear+clen+2, &c, 2);
clen += 4;
@@ -359,11 +336,7 @@ calc_hash(struct query_info* qinfo, struct module_env* env, char* buf,
/* hash the buffer */
secalgo_hash_sha256(clear, clen, hash);
#ifdef HAVE_EXPLICIT_BZERO
explicit_bzero(clear, clen);
#else
memset(clear, 0, clen);
#endif
/* hex encode output for portability (some online dbs need
* no nulls, no control characters, and so on) */
@@ -392,33 +365,13 @@ prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
if(!qstate->return_msg || !qstate->return_msg->rep)
return 0;
/* do not store failures like SERVFAIL in the cachedb, this avoids
* overwriting expired, valid, content with broken content. */
if(FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags) !=
LDNS_RCODE_YXDOMAIN)
/* We don't store the reply if its TTL is 0 unless serve-expired is
* enabled. Such a reply won't be reusable and simply be a waste for
* the backend. It's also compatible with the default behavior of
* dns_cache_store_msg(). */
if(qstate->return_msg->rep->ttl == 0 &&
!qstate->env->cfg->serve_expired)
return 0;
/* Do not persist data the validator has not yet seen, or has rejected.
* Otherwise an expired blob could maybe reach clients via
* serve-expired. */
if(qstate->env->need_to_validate &&
qstate->return_msg->rep->security == sec_status_bogus)
return 0;
/* We don't store the reply if its TTL is 0. This is probably coming
* from upstream and it is not meant to be stored. */
if(qstate->return_msg->rep->ttl == 0)
return 0;
/* The EDE is added to the out-list so it is encoded in the cached message */
if (qstate->env->cfg->ede && qstate->return_msg->rep->reason_bogus != LDNS_EDE_NONE) {
edns_opt_list_append_ede(&edns.opt_list_out, qstate->env->scratch,
qstate->return_msg->rep->reason_bogus,
qstate->return_msg->rep->reason_bogus_str);
}
if(verbosity >= VERB_ALGO)
log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
qstate->return_msg->rep);
@@ -459,14 +412,8 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
&expiry, sizeof(expiry));
expiry = be64toh(expiry);
/* Check if we are allowed to return expired entries:
* - serve_expired needs to be set
* - if SERVE_EXPIRED_TTL is set make sure that the record is not older
* than that. */
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now) &&
(!qstate->env->cfg->serve_expired ||
(SERVE_EXPIRED_TTL &&
*qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
if((time_t)expiry < *qstate->env->now &&
!qstate->env->cfg->serve_expired)
return 0;
return 1;
@@ -475,77 +422,44 @@ good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
* negative, set the TTL to 0. */
static void
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract,
time_t timestamp)
packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
{
size_t i;
size_t total = data->count + data->rrsig_count;
size_t i;
size_t total = data->count + data->rrsig_count;
if(subtract >= 0 && data->ttl > subtract)
data->ttl -= subtract;
else data->ttl = 0;
for(i=0; i<total; i++) {
for(i=0; i<total; i++) {
if(subtract >= 0 && data->rr_ttl[i] > subtract)
data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0;
data->rr_ttl[i] -= subtract;
else data->rr_ttl[i] = 0;
}
data->ttl_add = timestamp;
}
/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
* negative, set the TTLs to 0. */
static void
adjust_msg_ttl(struct dns_msg* msg, time_t adjust, time_t timestamp)
adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
{
size_t i;
if(adjust >= 0 && msg->rep->ttl > adjust)
msg->rep->ttl -= adjust;
else
msg->rep->ttl = 0;
else msg->rep->ttl = 0;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, adjust, timestamp);
}
}
/* Set the TTL of the given RRset to fixed value. */
static void
packed_rrset_ttl_set(struct packed_rrset_data* data, time_t ttl, time_t timestamp)
{
size_t i;
size_t total = data->count + data->rrsig_count;
data->ttl = ttl;
for(i=0; i<total; i++) {
data->rr_ttl[i] = ttl;
}
data->ttl_add = timestamp;
}
/* Set the TTL of a DNS message and its RRs by to a fixed value. */
static void
set_msg_ttl(struct dns_msg* msg, time_t ttl, time_t timestamp)
{
size_t i;
msg->rep->ttl = ttl;
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
for(i=0; i<msg->rep->rrset_count; i++) {
packed_rrset_ttl_set((struct packed_rrset_data*)msg->
rep->rrsets[i]->entry.data, ttl, timestamp);
rep->rrsets[i]->entry.data, adjust);
}
}
/** convert dns message in buffer to return_msg */
static int
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
{
struct msg_parse* prs;
struct edns_data edns;
struct edns_option* ede;
uint64_t timestamp, expiry;
time_t adjust;
size_t lim = sldns_buffer_limit(buf);
@@ -558,9 +472,6 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
&timestamp, sizeof(timestamp));
expiry = be64toh(expiry);
timestamp = be64toh(timestamp);
log_assert(timestamp <= expiry);
*msg_expiry = (time_t)expiry;
*msg_timestamp = (time_t)timestamp;
/* parse DNS packet */
regional_free_all(qstate->env->scratch);
@@ -575,7 +486,7 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
sldns_buffer_set_limit(buf, lim);
return 0;
}
if(parse_extract_edns_from_response_msg(prs, &edns, qstate->env->scratch) !=
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
LDNS_RCODE_NOERROR) {
sldns_buffer_set_limit(buf, lim);
return 0;
@@ -586,24 +497,6 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
if(!qstate->return_msg)
return 0;
/* We find the EDE in the in-list after parsing */
if(qstate->env->cfg->ede &&
(ede = edns_opt_list_find(edns.opt_list_in, LDNS_EDNS_EDE))) {
if(ede->opt_len >= 2) {
qstate->return_msg->rep->reason_bogus =
sldns_read_uint16(ede->opt_data);
}
/* allocate space and store the error string and it's size */
if(ede->opt_len > 2) {
size_t ede_len = ede->opt_len - 2;
qstate->return_msg->rep->reason_bogus_str = regional_alloc(
qstate->region, sizeof(char) * (ede_len+1));
memcpy(qstate->return_msg->rep->reason_bogus_str,
ede->opt_data+2, ede_len);
qstate->return_msg->rep->reason_bogus_str[ede_len] = 0;
}
}
qstate->return_rcode = LDNS_RCODE_NOERROR;
/* see how much of the TTL expired, and remove it */
@@ -612,32 +505,25 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
return 1; /* message from the future (clock skew?) */
}
adjust = *qstate->env->now - (time_t)timestamp;
if(TTL_IS_EXPIRED((time_t)expiry, *qstate->env->now)) {
if(qstate->return_msg->rep->ttl < adjust) {
verbose(VERB_ALGO, "cachedb msg expired");
*msg_expired = 1;
if(!qstate->env->cfg->serve_expired ||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
if(qstate->env->cfg->serve_expired)
adjust = -1;
else
return 0; /* message expired */
/* If serve-expired is enabled, we still use an expired message.
* Set the TTL to 0 now and it will be handled specially later
* when we need to store it internally. */
adjust = -1;
}
adjust_msg_ttl(qstate->return_msg, adjust, timestamp);
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
if(qstate->env->cfg->aggressive_nsec) {
limit_nsec_ttl(qstate->return_msg);
}
adjust_msg_ttl(qstate->return_msg, adjust);
/* Similar to the unbound worker, if serve-expired is enabled and
* the msg would be considered to be expired, mark the state so a
* refetch will be scheduled. */
if(*msg_expired && !qstate->env->cfg->serve_expired_client_timeout) {
* refetch will be scheduled. The comparison between 'expiry' and
* 'now' should be redundant given how these values were calculated,
* but we check it just in case as does good_expiry_and_qinfo(). */
if(qstate->env->cfg->serve_expired &&
(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
qstate->need_refetch = 1;
}
@@ -649,11 +535,10 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf,
* return true if lookup was successful.
*/
static int
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
int* msg_expired, time_t* msg_timestamp, time_t* msg_expiry)
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
calc_hash(qstate, key, sizeof(key));
/* call backend to fetch data for key into scratch buffer */
if( !(*ie->backend->lookup)(qstate->env, ie, key,
@@ -667,8 +552,7 @@ cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie,
}
/* parse dns message into return_msg */
if( !parse_data(qstate, qstate->env->scratch_buffer, msg_expired,
msg_timestamp, msg_expiry) ) {
if( !parse_data(qstate, qstate->env->scratch_buffer) ) {
return 0;
}
return 1;
@@ -681,7 +565,7 @@ static void
cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
calc_hash(&qstate->qinfo, qstate->env, key, sizeof(key));
calc_hash(qstate, key, sizeof(key));
/* prepare data in scratch buffer */
if(!prep_data(qstate, qstate->env->scratch_buffer))
@@ -690,33 +574,21 @@ 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),
qstate->return_msg->rep->ttl);
sldns_buffer_limit(qstate->env->scratch_buffer));
}
/**
* See if unbound's internal cache can answer the query
*/
static int
cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
cachedb_intcache_lookup(struct module_qstate* qstate)
{
uint8_t dpname_storage[LDNS_MAX_DOMAINLEN+1];
uint8_t* dpname=NULL;
size_t dpnamelen=0;
struct dns_msg* msg;
/* for testframe bypass this lookup */
if(cde->backend == &testframe_backend) {
return 0;
}
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo,
&dpname, &dpnamelen, dpname_storage, sizeof(dpname_storage)))
return 0; /* no cache for these queries */
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
qstate->qinfo.qname_len, qstate->qinfo.qtype,
qstate->qinfo.qclass, qstate->query_flags,
qstate->region, qstate->env->scratch,
1, /* no partial messages with only a CNAME */
dpname, dpnamelen
1 /* no partial messages with only a CNAME */
);
if(!msg && qstate->env->neg_cache &&
iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
@@ -740,52 +612,17 @@ cachedb_intcache_lookup(struct module_qstate* qstate, struct cachedb_env* cde)
* Store query into the internal cache of unbound.
*/
static void
cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
time_t msg_timestamp, time_t msg_expiry)
cachedb_intcache_store(struct module_qstate* qstate)
{
uint32_t store_flags = qstate->query_flags;
int serve_expired = qstate->env->cfg->serve_expired;
if(qstate->env->cfg->serve_expired)
store_flags |= DNSCACHE_STORE_ZEROTTL;
if(!qstate->return_msg)
return;
if(serve_expired && msg_expired) {
time_t original_ttl = msg_expiry - msg_timestamp;
store_flags |= DNSCACHE_STORE_EXPIRED_MSG_CACHEDB;
/* Pass the original TTL of the expired message and signal with
* the DNSCACHE_STORE_EXPIRED_MSG_CACHEDB flag that
* dns_cache_store_msg() needs to set absolute expired TTLs
* based on the original message TTL.
* Results as expired message in the cache */
set_msg_ttl(qstate->return_msg, original_ttl, 0);
verbose(VERB_ALGO, "cachedb expired msg set to be expired now "
"(original ttl: %d)", (int)original_ttl);
/* The expired entry does not get checked by the validator
* and we need a validation value for it. */
/* By setting this to unchecked, bogus data is not returned
* as non-bogus. */
if(qstate->env->cfg->cachedb_check_when_serve_expired)
qstate->return_msg->rep->security = sec_status_unchecked;
}
(void)dns_cache_store(qstate->env, &qstate->qinfo,
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
qstate->region, store_flags, qstate->qstarttime,
qstate->is_valrec);
if(serve_expired && msg_expired) {
if(qstate->env->cfg->serve_expired_client_timeout) {
/* No expired response from the query state, the
* query resolution needs to continue and it can
* pick up the expired result after the timer out
* of cache. */
return;
}
/* Send serve expired responses based on the cachedb
* returned message, that was just stored in the cache.
* It can then continue to work on this query. */
mesh_respond_serve_expired(qstate->mesh_info);
/* set TTLs as expired for this return_msg in case it is used
* later on */
set_msg_ttl(qstate->return_msg,
EXPIRED_REPLY_TTL_CALC(msg_expiry, msg_timestamp), 0);
}
qstate->region, store_flags);
}
/**
@@ -801,9 +638,6 @@ cachedb_handle_query(struct module_qstate* qstate,
struct cachedb_qstate* ATTR_UNUSED(iq),
struct cachedb_env* ie, int id)
{
int msg_expired = 0;
time_t msg_timestamp, msg_expiry;
qstate->is_cachedb_answer = 0;
/* check if we are enabled, and skip if so */
if(!ie->enabled) {
/* pass request to next module */
@@ -811,28 +645,23 @@ cachedb_handle_query(struct module_qstate* qstate,
return;
}
if(qstate->blacklist || qstate->no_cache_lookup
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
NULL, 0)) {
/* cache is blacklisted or we are instructed from edns to not
* look or a forwarder/stub forbids it */
if(qstate->blacklist || qstate->no_cache_lookup) {
/* cache is blacklisted or we are instructed from edns to not look */
/* pass request to next module */
qstate->ext_state[id] = module_wait_module;
return;
}
/* lookup inside unbound's internal cache.
* This does not look for expired entries. */
if(cachedb_intcache_lookup(qstate, ie)) {
/* lookup inside unbound's internal cache */
if(cachedb_intcache_lookup(qstate)) {
if(verbosity >= VERB_ALGO) {
if(qstate->return_msg->rep)
log_dns_msg("cachedb internal cache lookup",
&qstate->return_msg->qinfo,
qstate->return_msg->rep);
else log_info("cachedb internal cache lookup: rcode %s",
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)
?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name
:"??");
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
}
/* we are done with the query */
qstate->ext_state[id] = module_finished;
@@ -840,55 +669,18 @@ cachedb_handle_query(struct module_qstate* qstate,
}
/* ask backend cache to see if we have data */
if(cachedb_extcache_lookup(qstate, ie, &msg_expired, &msg_timestamp,
&msg_expiry)) {
if(cachedb_extcache_lookup(qstate, ie)) {
if(verbosity >= VERB_ALGO)
log_dns_msg(ie->backend->name,
&qstate->return_msg->qinfo,
qstate->return_msg->rep);
/* store this result in internal cache */
cachedb_intcache_store(qstate,
msg_expired, msg_timestamp, msg_expiry);
/* In case we have expired data but there is a client timer for expired
* answers, pass execution to next module in order to try updating the
* data first.
*/
if(qstate->env->cfg->serve_expired && msg_expired) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_wait_module;
/* The expired reply is sent with
* mesh_respond_serve_expired, and so
* the need_refetch is not used. */
qstate->need_refetch = 0;
return;
}
if(qstate->need_refetch && qstate->serve_expired_data &&
qstate->serve_expired_data->timer) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_wait_module;
return;
}
/* No 0TTL answers escaping from external cache. */
if(qstate->return_msg->rep->ttl == 0) {
qstate->return_msg = NULL;
qstate->ext_state[id] = module_wait_module;
return;
}
log_assert(qstate->return_msg->rep->ttl > 0);
qstate->is_cachedb_answer = 1;
cachedb_intcache_store(qstate);
/* we are done with the query */
qstate->ext_state[id] = module_finished;
return;
}
if(qstate->serve_expired_data &&
qstate->env->cfg->cachedb_check_when_serve_expired &&
!qstate->env->cfg->serve_expired_client_timeout) {
/* Reply with expired data if any to client, because cachedb
* also has no useful, current data */
mesh_respond_serve_expired(qstate->mesh_info);
}
/* no cache fetches */
/* pass request to next module */
qstate->ext_state[id] = module_wait_module;
@@ -906,20 +698,12 @@ static void
cachedb_handle_response(struct module_qstate* qstate,
struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
{
qstate->is_cachedb_answer = 0;
/* check if we are not enabled or instructed to not cache, and skip */
if(!ie->enabled || qstate->no_cache_store
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
NULL, 0)) {
if(!ie->enabled || qstate->no_cache_store) {
/* we are done with the query */
qstate->ext_state[id] = module_finished;
return;
}
if(qstate->env->cfg->cachedb_no_store) {
/* do not store the item in the external cache */
qstate->ext_state[id] = module_finished;
return;
}
/* store the item into the backend cache */
cachedb_extcache_store(qstate, ie);
@@ -1014,7 +798,7 @@ cachedb_get_mem(struct module_env* env, int id)
*/
static struct module_func_block cachedb_block = {
"cachedb",
NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
&cachedb_init, &cachedb_deinit, &cachedb_operate,
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
};
@@ -1023,41 +807,4 @@ cachedb_get_funcblock(void)
{
return &cachedb_block;
}
int
cachedb_is_enabled(struct module_stack* mods, struct module_env* env)
{
struct cachedb_env* ie;
int id = modstack_find(mods, "cachedb");
if(id == -1)
return 0;
ie = (struct cachedb_env*)env->modinfo[id];
if(ie && ie->enabled)
return 1;
return 0;
}
void cachedb_msg_remove(struct module_qstate* qstate)
{
cachedb_msg_remove_qinfo(qstate->env, &qstate->qinfo);
}
void cachedb_msg_remove_qinfo(struct module_env* env, struct query_info* qinfo)
{
char key[(CACHEDB_HASHSIZE/8)*2+1];
int id = modstack_find(env->modstack, "cachedb");
struct cachedb_env* ie = (struct cachedb_env*)env->modinfo[id];
log_query_info(VERB_ALGO, "cachedb msg remove", qinfo);
calc_hash(qinfo, env, key, sizeof(key));
sldns_buffer_clear(env->scratch_buffer);
sldns_buffer_write_u32(env->scratch_buffer, 0);
sldns_buffer_flip(env->scratch_buffer);
/* call backend */
(*ie->backend->store)(env, ie, key,
sldns_buffer_begin(env->scratch_buffer),
sldns_buffer_limit(env->scratch_buffer),
0);
}
#endif /* USE_CACHEDB */
+1 -25
View File
@@ -41,7 +41,6 @@
*/
#include "util/module.h"
struct cachedb_backend;
struct module_stack;
/**
* The global variable environment contents for the cachedb
@@ -85,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, time_t);
uint8_t*, size_t);
};
#define CACHEDB_HASHSIZE 256 /* bit hash */
@@ -111,26 +110,3 @@ size_t cachedb_get_mem(struct module_env* env, int id);
*/
struct module_func_block* cachedb_get_funcblock(void);
/**
* See if the cachedb is enabled.
* @param mods: module stack. It finds the cachedb module environment.
* @param env: module environment.
* @return true if exists and enabled.
*/
int cachedb_is_enabled(struct module_stack* mods, struct module_env* env);
/**
* Remove a message from the global cache. Because edns subnet has a more
* specific entry, and if not removed when everything expires, the global
* entry is used, instead of a fresh lookup of the edns subnet entry.
* @param qstate: query state.
*/
void cachedb_msg_remove(struct module_qstate* qstate);
/**
* Remove message from the cachedb cache, by query info.
* @param env: module environment to look up cachedb state.
* @param qinfo: the message to remove.
*/
void cachedb_msg_remove_qinfo(struct module_env* env,
struct query_info* qinfo);
+55 -409
View File
@@ -46,363 +46,75 @@
#include "cachedb/cachedb.h"
#include "util/alloc.h"
#include "util/config_file.h"
#include "util/locks.h"
#include "util/timeval_func.h"
#include "sldns/sbuffer.h"
#ifdef USE_REDIS
#include "hiredis/hiredis.h"
struct redis_moddata {
/* thread-specific redis contexts */
redisContext** ctxs;
redisContext** replica_ctxs;
/* number of ctx entries */
int numctxs;
/* server's IP address or host name */
const char* server_host;
const char* replica_server_host;
/* server's TCP port */
int server_port;
int replica_server_port;
/* server's unix path, or "", NULL if unused */
const char* server_path;
const char* replica_server_path;
/* server's AUTH password, or "", NULL if unused */
const char* server_password;
const char* replica_server_password;
/* timeout for commands */
struct timeval command_timeout;
struct timeval replica_command_timeout;
/* timeout for connection setup */
struct timeval connect_timeout;
struct timeval replica_connect_timeout;
/* the reconnect interval time. */
struct timeval reconnect_interval;
struct timeval replica_reconnect_interval;
/* reconnect attempts, 0 if connected, counts up failed reconnects. */
int reconnect_attempts;
int replica_reconnect_attempts;
/* Lock on reconnect_wait time. */
lock_basic_type wait_lock;
lock_basic_type replica_wait_lock;
/* reconnect wait time, wait until it has passed before reconnect. */
struct timeval reconnect_wait;
struct timeval replica_reconnect_wait;
/* the redis logical database to use */
int logical_db;
int replica_logical_db;
/* if the SET with EX command is supported */
int set_with_ex_available;
redisContext** ctxs; /* thread-specific redis contexts */
int numctxs; /* number of ctx entries */
const char* server_host; /* server's IP address or host name */
int server_port; /* server's TCP port */
struct timeval timeout; /* timeout for connection setup and commands */
};
/** The limit on the number of redis connect attempts. After failure if
* the number is exceeded, the reconnects are throttled by the wait time. */
#define REDIS_RECONNECT_ATTEMPT_LIMIT 3
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
const char*, const uint8_t*, size_t, int);
static void
moddata_clean(struct redis_moddata** moddata) {
if(!moddata || !*moddata)
return;
if((*moddata)->ctxs) {
int i;
for(i = 0; i < (*moddata)->numctxs; i++) {
if((*moddata)->ctxs[i])
redisFree((*moddata)->ctxs[i]);
}
free((*moddata)->ctxs);
}
if((*moddata)->replica_ctxs) {
int i;
for(i = 0; i < (*moddata)->numctxs; i++) {
if((*moddata)->replica_ctxs[i])
redisFree((*moddata)->replica_ctxs[i]);
}
free((*moddata)->replica_ctxs);
}
lock_basic_destroy(&(*moddata)->wait_lock);
lock_basic_destroy(&(*moddata)->replica_wait_lock);
free(*moddata);
*moddata = NULL;
}
static redisContext*
redis_connect(const char* host, int port, const char* path,
const char* password, int logical_db,
const struct timeval connect_timeout,
const struct timeval command_timeout,
const struct timeval* reconnect_interval,
int* reconnect_attempts,
struct timeval* reconnect_wait,
lock_basic_type* wait_lock,
struct timeval* now_tv,
const char* infostr)
redis_connect(const struct redis_moddata* moddata)
{
struct timeval now_val;
redisContext* ctx;
#ifdef THREADS_DISABLED
/* Fix attribute unused warning.
* wait_lock is only used with lock_basic_* functions that are nop'ed
* when compiled without thread support. */
(void)wait_lock;
#endif /* THREADS_DISABLED */
/* See if the redis server is down, and reconnect has to wait. */
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Acquire lock to look at timeval, the integer has atomic
* integrity. */
struct timeval wait_tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
lock_basic_lock(wait_lock);
wait_tv = *reconnect_wait;
lock_basic_unlock(wait_lock);
if(timeval_smaller(&now_val, &wait_tv)) {
verbose(VERB_ALGO, "redis %sdown, reconnect wait",
infostr);
return NULL;
}
}
if(path && path[0]!=0) {
ctx = redisConnectUnixWithTimeout(path, connect_timeout);
} else {
ctx = redisConnectWithTimeout(host, port, connect_timeout);
}
ctx = redisConnectWithTimeout(moddata->server_host,
moddata->server_port, moddata->timeout);
if(!ctx || ctx->err) {
const char *errstr = "out of memory";
if(ctx)
errstr = ctx->errstr;
log_err("failed to connect to redis %sserver: %s", infostr, errstr);
log_err("failed to connect to redis server: %s", errstr);
goto fail;
}
if(redisSetTimeout(ctx, command_timeout) != REDIS_OK) {
log_err("failed to set redis %stimeout, %s", infostr, ctx->errstr);
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
log_err("failed to set redis timeout");
goto fail;
}
if(password && password[0]!=0) {
redisReply* rep;
rep = redisCommand(ctx, "AUTH %s", password);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed to authenticate %swith password", infostr);
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
if(logical_db > 0) {
redisReply* rep;
rep = redisCommand(ctx, "SELECT %d", logical_db);
if(!rep || rep->type == REDIS_REPLY_ERROR) {
log_err("failed %sto set logical database (%d)",
infostr, logical_db);
freeReplyObject(rep);
goto fail;
}
freeReplyObject(rep);
}
*reconnect_attempts = 0;
if(verbosity >= VERB_OPS) {
char port_str[6+1];
port_str[0] = ' ';
(void)snprintf(port_str+1, sizeof(port_str)-1, "%d", port);
verbose(VERB_OPS, "Connection to Redis %sestablished (%s%s)",
infostr,
path&&path[0]!=0?path:host,
path&&path[0]!=0?"":port_str);
}
return ctx;
fail:
fail:
if(ctx)
redisFree(ctx);
(*reconnect_attempts)++;
if(*reconnect_attempts > REDIS_RECONNECT_ATTEMPT_LIMIT) {
/* Wait for the reconnect interval before trying again. */
struct timeval tv;
if(now_tv) {
now_val = *now_tv;
} else {
if(gettimeofday(&now_val, NULL) < 0)
log_err("redis: gettimeofday: %s",
strerror(errno));
}
tv = now_val;
timeval_add(&tv, reconnect_interval);
lock_basic_lock(wait_lock);
*reconnect_wait = tv;
lock_basic_unlock(wait_lock);
verbose(VERB_ALGO, "redis %sreconnect wait until %d.%6.6d",
infostr, (int)tv.tv_sec, (int)tv.tv_usec);
}
return NULL;
}
static void
set_timeout(struct timeval* timeout, int value, int explicit_value)
{
int v = explicit_value != 0 ? explicit_value : value;
timeout->tv_sec = v / 1000;
timeout->tv_usec = (v % 1000) * 1000;
}
static int
redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
{
int i;
struct redis_moddata* moddata = NULL;
verbose(VERB_OPS, "Redis initialization");
verbose(VERB_ALGO, "redis_init");
moddata = calloc(1, sizeof(struct redis_moddata));
if(!moddata) {
log_err("out of memory");
goto fail;
return 0;
}
lock_basic_init(&moddata->wait_lock);
lock_protect(&moddata->wait_lock, &moddata->reconnect_wait,
sizeof(moddata->reconnect_wait));
lock_basic_init(&moddata->replica_wait_lock);
lock_protect(&moddata->replica_wait_lock,
&moddata->replica_reconnect_wait,
sizeof(moddata->replica_reconnect_wait));
moddata->numctxs = env->cfg->num_threads;
/* note: server_host and similar string configuration options are
* shallow references to configured strings; we don't have to free them
* in this module. */
moddata->server_host = env->cfg->redis_server_host;
moddata->replica_server_host = env->cfg->redis_replica_server_host;
moddata->server_port = env->cfg->redis_server_port;
moddata->replica_server_port = env->cfg->redis_replica_server_port;
moddata->server_path = env->cfg->redis_server_path;
moddata->replica_server_path = env->cfg->redis_replica_server_path;
moddata->server_password = env->cfg->redis_server_password;
moddata->replica_server_password = env->cfg->redis_replica_server_password;
set_timeout(&moddata->command_timeout,
env->cfg->redis_timeout,
env->cfg->redis_command_timeout);
set_timeout(&moddata->replica_command_timeout,
env->cfg->redis_replica_timeout,
env->cfg->redis_replica_command_timeout);
set_timeout(&moddata->connect_timeout,
env->cfg->redis_timeout,
env->cfg->redis_connect_timeout);
set_timeout(&moddata->replica_connect_timeout,
env->cfg->redis_replica_timeout,
env->cfg->redis_replica_connect_timeout);
set_timeout(&moddata->reconnect_interval, 1000, 0);
set_timeout(&moddata->replica_reconnect_interval, 1000, 0);
moddata->logical_db = env->cfg->redis_logical_db;
moddata->replica_logical_db = env->cfg->redis_replica_logical_db;
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
if(!moddata->ctxs) {
log_err("out of memory");
goto fail;
}
if((moddata->replica_server_host && moddata->replica_server_host[0]!=0)
|| (moddata->replica_server_path && moddata->replica_server_path[0]!=0)) {
/* There is a replica configured, allocate ctxs */
moddata->replica_ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
if(!moddata->replica_ctxs) {
log_err("out of memory");
goto fail;
}
}
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(
moddata->server_host,
moddata->server_port,
moddata->server_path,
moddata->server_password,
moddata->logical_db,
moddata->connect_timeout,
moddata->command_timeout,
&moddata->reconnect_interval,
&moddata->reconnect_attempts,
&moddata->reconnect_wait,
&moddata->wait_lock,
env->now_tv,
"");
if(!ctx) {
log_err("redis_init: failed to init redis "
"(for thread %d)", i);
/* And continue, the context can be established
* later, just like after a disconnect. */
}
moddata->ctxs[i] = ctx;
}
if(moddata->replica_ctxs) {
for(i = 0; i < moddata->numctxs; i++) {
redisContext* ctx = redis_connect(
moddata->replica_server_host,
moddata->replica_server_port,
moddata->replica_server_path,
moddata->replica_server_password,
moddata->replica_logical_db,
moddata->replica_connect_timeout,
moddata->replica_command_timeout,
&moddata->replica_reconnect_interval,
&moddata->replica_reconnect_attempts,
&moddata->replica_reconnect_wait,
&moddata->replica_wait_lock,
env->now_tv,
"replica ");
if(!ctx) {
log_err("redis_init: failed to init redis "
"replica (for thread %d)", i);
/* And continue, the context can be established
* later, just like after a disconnect. */
}
moddata->replica_ctxs[i] = ctx;
}
free(moddata);
return 0;
}
/* note: server_host is a shallow reference to configured string.
* we don't have to free it in this module. */
moddata->server_host = env->cfg->redis_server_host;
moddata->server_port = env->cfg->redis_server_port;
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
for(i = 0; i < moddata->numctxs; i++)
moddata->ctxs[i] = redis_connect(moddata);
cachedb_env->backend_data = moddata;
if(env->cfg->redis_expire_records &&
moddata->ctxs[env->alloc->thread_num] != NULL) {
redisReply* rep = NULL;
int redis_reply_type = 0;
/** check if set with ex command is supported */
rep = redis_command(env, cachedb_env,
"SET __UNBOUND_REDIS_CHECK__ none EX 1", NULL, 0, 1);
if(!rep) {
/** init failed, no response from redis server*/
goto set_with_ex_fail;
}
redis_reply_type = rep->type;
freeReplyObject(rep);
switch(redis_reply_type) {
case REDIS_REPLY_STATUS:
break;
default:
/** init failed, set_with_ex command not supported */
goto set_with_ex_fail;
}
moddata->set_with_ex_available = 1;
}
return 1;
set_with_ex_fail:
log_err("redis_init: failure during redis_init, the "
"redis-expire-records option requires the SET with EX command "
"(redis >= 2.6.12)");
return 1;
fail:
moddata_clean(&moddata);
return 0;
}
static void
@@ -412,8 +124,19 @@ redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
cachedb_env->backend_data;
(void)env;
verbose(VERB_OPS, "Redis deinitialization");
moddata_clean(&moddata);
verbose(VERB_ALGO, "redis_deinit");
if(!moddata)
return;
if(moddata->ctxs) {
int i;
for(i = 0; i < moddata->numctxs; i++) {
if(moddata->ctxs[i])
redisFree(moddata->ctxs[i]);
}
free(moddata->ctxs);
}
free(moddata);
}
/*
@@ -430,9 +153,9 @@ redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
*/
static redisReply*
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
const char* command, const uint8_t* data, size_t data_len, int write)
const char* command, const uint8_t* data, size_t data_len)
{
redisContext* ctx, **ctx_selector;
redisContext* ctx;
redisReply* rep;
struct redis_moddata* d = (struct redis_moddata*)
cachedb_env->backend_data;
@@ -443,50 +166,17 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
* assumption throughout the unbound architecture, so we simply assert
* it. */
log_assert(env->alloc->thread_num < d->numctxs);
ctx_selector = !write && d->replica_ctxs
?d->replica_ctxs
:d->ctxs;
ctx = ctx_selector[env->alloc->thread_num];
ctx = d->ctxs[env->alloc->thread_num];
/* If we've not established a connection to the server or we've closed
* it on a failure, try to re-establish a new one. Failures will be
* logged in redis_connect(). */
if(!ctx) {
if(!write && d->replica_ctxs) {
ctx = redis_connect(
d->replica_server_host,
d->replica_server_port,
d->replica_server_path,
d->replica_server_password,
d->replica_logical_db,
d->replica_connect_timeout,
d->replica_command_timeout,
&d->replica_reconnect_interval,
&d->replica_reconnect_attempts,
&d->replica_reconnect_wait,
&d->replica_wait_lock,
env->now_tv,
"replica ");
} else {
ctx = redis_connect(
d->server_host,
d->server_port,
d->server_path,
d->server_password,
d->logical_db,
d->connect_timeout,
d->command_timeout,
&d->reconnect_interval,
&d->reconnect_attempts,
&d->reconnect_wait,
&d->wait_lock,
env->now_tv,
"");
}
ctx_selector[env->alloc->thread_num] = ctx;
ctx = redis_connect(d);
d->ctxs[env->alloc->thread_num] = ctx;
}
if(!ctx) return NULL;
if(!ctx)
return NULL;
/* Send the command and get a reply, synchronously. */
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
@@ -496,7 +186,7 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
log_err("redis_command: failed to receive a reply, "
"closing connection: %s", ctx->errstr);
redisFree(ctx);
ctx_selector[env->alloc->thread_num] = NULL;
d->ctxs[env->alloc->thread_num] = NULL;
return NULL;
}
@@ -514,14 +204,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
char* key, struct sldns_buffer* result_buffer)
{
redisReply* rep;
/* Supported commands:
* - "GET " + key
*/
#define REDIS_LOOKUP_MAX_BUF_LEN \
4 /* "GET " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 1 /* \0 */
char cmdbuf[REDIS_LOOKUP_MAX_BUF_LEN];
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
int n;
int ret = 0;
@@ -533,10 +216,10 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
return 0;
}
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0, 0);
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;
@@ -566,63 +249,26 @@ 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, time_t ttl)
char* key, uint8_t* data, size_t data_len)
{
redisReply* rep;
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
int n;
struct redis_moddata* moddata = (struct redis_moddata*)
cachedb_env->backend_data;
int set_ttl = (moddata->set_with_ex_available &&
env->cfg->redis_expire_records &&
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
/* Supported commands:
* - "SET " + key + " %b"
* - "SET " + key + " %b EX " + ttl
* older redis 2.0.0 was "SETEX " + key + " " + ttl + " %b"
* - "EXPIRE " + key + " 0"
*/
#define REDIS_STORE_MAX_BUF_LEN \
7 /* "EXPIRE " */ \
+(CACHEDB_HASHSIZE/8)*2 /* key hash */ \
+ 7 /* " %b EX " */ \
+ 20 /* ttl (uint64_t) */ \
+ 1 /* \0 */
char cmdbuf[REDIS_STORE_MAX_BUF_LEN];
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 if(ttl == 0) {
/* use the EXPIRE command, SET with EX 0 is an invalid time. */
/* Replies with REDIS_REPLY_INTEGER of 1. */
verbose(VERB_ALGO, "redis_store expire %s (%d bytes)",
key, (int)data_len);
n = snprintf(cmdbuf, sizeof(cmdbuf), "EXPIRE %s 0", key);
data = NULL;
data_len = 0;
} 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, (unsigned)(uint32_t)ttl);
/* build command to set to a binary safe string */
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b EX %u", key,
(unsigned)(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;
}
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len, 1);
rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
if(rep) {
verbose(VERB_ALGO, "redis_store set completed");
if(rep->type != REDIS_REPLY_STATUS &&
rep->type != REDIS_REPLY_ERROR &&
rep->type != REDIS_REPLY_INTEGER) {
rep->type != REDIS_REPLY_ERROR) {
log_err("redis_store: unexpected type of reply (%d)",
rep->type);
}
+1 -14
View File
@@ -38,9 +38,6 @@
#ifndef UB_ON_WINDOWS
#include <sys/mman.h>
#endif
#ifdef __QNX__
#include "util/log.h"
#endif /* __QNX__ */
#define KEYSTREAM_ONLY
#include "chacha_private.h"
@@ -60,8 +57,6 @@
#define BLOCKSZ 64
#define RSBUFSZ (16*BLOCKSZ)
#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
static struct {
size_t rs_have; /* valid bytes at end of rs_buf */
@@ -184,17 +179,12 @@ static void
_rs_stir(void)
{
u_char rnd[KEYSZ + IVSZ];
uint32_t rekey_fuzz = 0;
if (getentropy(rnd, sizeof rnd) == -1) {
if(errno != ENOSYS ||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
#ifdef SIGKILL
#ifndef __QNX__
raise(SIGKILL);
#else /* !__QNX__ */
fatal_exit("failed to getentropy");
#endif /* __QNX__ */
#else
exit(9); /* windows */
#endif
@@ -211,10 +201,7 @@ _rs_stir(void)
rs->rs_have = 0;
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
/* rekey interval should not be predictable */
chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
(uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
rs->rs_count = 1600000;
}
static inline void
+2 -2
View File
@@ -48,8 +48,8 @@ typedef struct
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static const char ATTR_NONSTRING(sigma[16]) = "expand 32-byte k";
static const char ATTR_NONSTRING(tau[16]) = "expand 16-byte k";
static const char sigma[16] = "expand 32-byte k";
static const char tau[16] = "expand 16-byte k";
static void
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
+1 -1
View File
@@ -38,5 +38,5 @@ char *ctime_r(const time_t *timep, char *buf)
strcpy(buf, result);
}
lock_basic_unlock(&ctime_lock);
return buf;
return result;
}
+3 -3
View File
@@ -57,7 +57,7 @@ int getnameinfo(const struct sockaddr *sa, size_t ATTR_UNUSED(salen), char *host
}
if (host != NULL) {
if ((flags & NI_NUMERICHOST)) {
if (flags & NI_NUMERICHOST) {
if (strlcpy(host, inet_ntoa(sin->sin_addr),
hostlen) >= hostlen)
return (EAI_MEMORY);
@@ -168,7 +168,7 @@ getaddrinfo(const char *hostname, const char *servname,
port = 0;
}
if (hints && (hints->ai_flags & AI_PASSIVE)) {
if (hints && hints->ai_flags & AI_PASSIVE) {
addr = htonl(0x00000000);
if (hostname && inet_aton(hostname, &in) != 0)
addr = in.s_addr;
@@ -193,7 +193,7 @@ getaddrinfo(const char *hostname, const char *servname,
}
/* Don't try DNS if AI_NUMERICHOST is set */
if (hints && (hints->ai_flags & AI_NUMERICHOST))
if (hints && hints->ai_flags & AI_NUMERICHOST)
return (EAI_NONAME);
hp = gethostbyname(hostname);
-62
View File
@@ -1,62 +0,0 @@
/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */
/*
* Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* Copyright (c) 2014 Brent Cook <bcook@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include <sys/types.h>
#include <sys/sysctl.h>
#include <errno.h>
#include <stddef.h>
/*
* Derived from lib/libc/gen/arc4random.c from FreeBSD.
*/
static size_t
getentropy_sysctl(u_char *buf, size_t size)
{
int mib[2];
size_t len, done;
mib[0] = CTL_KERN;
mib[1] = KERN_ARND;
done = 0;
do {
len = size;
if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
return (done);
done += len;
buf += len;
size -= len;
} while (size > 0);
return (done);
}
int
getentropy(void *buf, size_t len)
{
if (len <= 256 && getentropy_sysctl(buf, len) == len)
return (0);
errno = EIO;
return (-1);
}
+84 -83
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $ */
/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -15,25 +15,20 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include "config.h"
/*
#define _POSIX_C_SOURCE 199309L
#define _GNU_SOURCE 1
#define _POSIX_C_SOURCE 199309L
#define _GNU_SOURCE 1
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#ifndef __QNX__
#include <sys/syscall.h>
#endif /* !__QNX__ */
#ifdef SYS__sysctl
#include <linux/sysctl.h>
#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif
#include <sys/statvfs.h>
#include <sys/socket.h>
@@ -44,9 +39,6 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#ifndef __QNX__
#include <link.h>
#endif /* __QNX__ */
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
@@ -54,24 +46,20 @@
#include <errno.h>
#include <unistd.h>
#include <time.h>
#ifndef HAVE_NETTLE
#if defined(HAVE_SSL)
#include <openssl/sha.h>
#else
#elif defined(HAVE_NETTLE)
#include <nettle/sha.h>
#define SHA512_CTX struct sha512_ctx
#define SHA512_Init(x) sha512_init(x)
#define SHA512_Update(x, b, s) sha512_update(x, s, b)
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
#endif
#ifndef __QNX__
#include <linux/types.h>
#include <linux/random.h>
#include <linux/sysctl.h>
#ifdef HAVE_GETAUXVAL
#include <sys/auxv.h>
#endif
#include <sys/vfs.h>
#endif /* !__QNX__ */
#ifndef MAP_ANON
#define MAP_ANON MAP_ANONYMOUS
#endif
@@ -87,23 +75,36 @@
HD(b); \
} while (0)
#if defined(HAVE_SSL)
#define CRYPTO_SHA512_CTX SHA512_CTX
#define CRYPTO_SHA512_INIT(x) SHA512_Init(x)
#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
#elif defined(HAVE_NETTLE)
#define CRYPTO_SHA512_CTX struct sha512_ctx
#define CRYPTO_SHA512_INIT(x) sha512_init(x)
#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
#define HF(x) (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x)))
#endif
int getentropy(void *buf, size_t len);
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
#ifdef CAN_REFERENCE_MAIN
extern int main(int, char *argv[]);
#endif
static int gotdata(char *buf, size_t len);
#if defined(SYS_getrandom) && defined(__NR_getrandom)
static int getentropy_getrandom(void *buf, size_t len);
#endif
static int getentropy_urandom(void *buf, size_t len);
#ifdef SYS__sysctl
static int getentropy_sysctl(void *buf, size_t len);
#endif
#ifndef __QNX__
static int getentropy_fallback(void *buf, size_t len);
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
#endif /* !__QNX__ */
int
getentropy(void *buf, size_t len)
@@ -112,21 +113,18 @@ getentropy(void *buf, size_t len)
if (len > 256) {
errno = EIO;
return (-1);
return -1;
}
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
#if defined(SYS_getrandom) && defined(__NR_getrandom)
/*
* Try descriptor-less getrandom(), in non-blocking mode.
*
* The design of Linux getrandom is broken. It has an
* uninitialized phase coupled with blocking behaviour, which
* is unacceptable from within a library at boot time without
* possible recovery. See http://bugs.python.org/issue26839#msg267745
* Try descriptor-less getrandom()
*/
ret = getentropy_getrandom(buf, len);
if (ret != -1)
return (ret);
if (errno != ENOSYS)
return (-1);
#endif
/*
@@ -180,13 +178,12 @@ getentropy(void *buf, size_t len)
* - Do the best under the circumstances....
*
* This code path exists to bring light to the issue that Linux
* still does not provide a failsafe API for entropy collection.
* does not provide a failsafe API for entropy collection.
*
* We hope this demonstrates that Linux should either retain their
* sysctl ABI, or consider providing a new failsafe API which
* works in a chroot or when file descriptors are exhausted.
*/
#ifndef __QNX__
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
raise(SIGKILL);
@@ -194,15 +191,28 @@ getentropy(void *buf, size_t len)
ret = getentropy_fallback(buf, len);
if (ret != -1)
return (ret);
#else /* !__QNX__ */
fatal_exit("failed to read from /dev/urandom");
#endif /* __QNX__ */
errno = EIO;
return (ret);
}
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
/*
* Basic sanity checking; wish we could do better.
*/
static int
gotdata(char *buf, size_t len)
{
char any_set = 0;
size_t i;
for (i = 0; i < len; ++i)
any_set |= buf[i];
if (any_set == 0)
return -1;
return 0;
}
#if defined(SYS_getrandom) && defined(__NR_getrandom)
static int
getentropy_getrandom(void *buf, size_t len)
{
@@ -211,7 +221,7 @@ getentropy_getrandom(void *buf, size_t len)
if (len > 256)
return (-1);
do {
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
ret = syscall(SYS_getrandom, buf, len, 0);
} while (ret == -1 && errno == EINTR);
if (ret != (int)len)
@@ -226,11 +236,7 @@ getentropy_urandom(void *buf, size_t len)
{
struct stat st;
size_t i;
#ifndef __QNX__
int fd, cnt, flags;
#else /* !__QNX__ */
int fd, flags;
#endif /* __QNX__ */
int save_errno = errno;
start:
@@ -257,15 +263,13 @@ start:
close(fd);
goto nodevrandom;
}
#ifndef __QNX__
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
close(fd);
goto nodevrandom;
}
#endif /* !__QNX__ */
for (i = 0; i < len; ) {
size_t wanted = len - i;
ssize_t ret = read(fd, (char *)buf + i, wanted);
ssize_t ret = read(fd, (char*)buf + i, wanted);
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
@@ -276,14 +280,15 @@ start:
i += ret;
}
close(fd);
errno = save_errno;
return (0); /* satisfied */
if (gotdata(buf, len) == 0) {
errno = save_errno;
return 0; /* satisfied */
}
nodevrandom:
errno = EIO;
return (-1);
return -1;
}
#ifndef __QNX__
#ifdef SYS__sysctl
static int
getentropy_sysctl(void *buf, size_t len)
@@ -306,15 +311,17 @@ getentropy_sysctl(void *buf, size_t len)
goto sysctlfailed;
i += chunk;
}
errno = save_errno;
return (0); /* satisfied */
if (gotdata(buf, len) == 0) {
errno = save_errno;
return (0); /* satisfied */
}
sysctlfailed:
errno = EIO;
return (-1);
return -1;
}
#endif /* SYS__sysctl */
static const int cl[] = {
static int cl[] = {
CLOCK_REALTIME,
#ifdef CLOCK_MONOTONIC
CLOCK_MONOTONIC,
@@ -339,15 +346,6 @@ static const int cl[] = {
#endif
};
static int
getentropy_phdr(struct dl_phdr_info *info, size_t ATTR_UNUSED(size), void *data)
{
SHA512_CTX *ctx = data;
SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
return (0);
}
static int
getentropy_fallback(void *buf, size_t len)
{
@@ -359,7 +357,7 @@ getentropy_fallback(void *buf, size_t len)
struct rusage ru;
sigset_t sigset;
struct stat st;
SHA512_CTX ctx;
CRYPTO_SHA512_CTX ctx;
static pid_t lastpid;
pid_t pid;
size_t i, ii, m;
@@ -376,7 +374,7 @@ getentropy_fallback(void *buf, size_t len)
}
for (i = 0; i < len; ) {
int j;
SHA512_Init(&ctx);
CRYPTO_SHA512_INIT(&ctx);
for (j = 0; j < repeat; j++) {
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
if (e != -1) {
@@ -384,8 +382,6 @@ getentropy_fallback(void *buf, size_t len)
cnt += (int)tv.tv_usec;
}
dl_iterate_phdr(getentropy_phdr, &ctx);
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
HX(clock_gettime(cl[ii], &ts) == -1, ts);
@@ -405,6 +401,9 @@ getentropy_fallback(void *buf, size_t len)
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
sigset);
#ifdef CAN_REFERENCE_MAIN
HF(main); /* an addr in program */
#endif
HF(getentropy); /* an addr in this library */
HF(printf); /* an addr in libc */
p = (char *)&p;
@@ -529,31 +528,33 @@ getentropy_fallback(void *buf, size_t len)
HD(cnt);
}
#ifdef HAVE_GETAUXVAL
#ifdef AT_RANDOM
# ifdef AT_RANDOM
/* Not as random as you think but we take what we are given */
p = (char *) getauxval(AT_RANDOM);
if (p)
HR(p, 16);
#endif
#ifdef AT_SYSINFO_EHDR
# endif
# ifdef AT_SYSINFO_EHDR
p = (char *) getauxval(AT_SYSINFO_EHDR);
if (p)
HR(p, pgs);
#endif
#ifdef AT_BASE
# endif
# ifdef AT_BASE
p = (char *) getauxval(AT_BASE);
if (p)
HD(p);
#endif
#endif
# endif
#endif /* HAVE_GETAUXVAL */
SHA512_Final(results, &ctx);
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
CRYPTO_SHA512_FINAL(results, &ctx);
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
i += min(sizeof(results), len - i);
}
explicit_bzero(&ctx, sizeof ctx);
explicit_bzero(results, sizeof results);
errno = save_errno;
return (0); /* satisfied */
memset(results, 0, sizeof results);
if (gotdata(buf, len) == 0) {
errno = save_errno;
return 0; /* satisfied */
}
errno = EIO;
return -1;
}
#endif /* !__QNX__ */
+400 -12
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $ */
/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -15,30 +15,418 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include "config.h"
/* Modified to use SecRandomCopyBytes. It is from macOS 10.7 (2011) and
* iOS 2.0 (2008), and is the primary API for cryptographic random numbers. */
#include <sys/types.h>
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/syscall.h>
#include <sys/sysctl.h>
#include <sys/statvfs.h>
#include <sys/socket.h>
#include <sys/mount.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <Security/SecRandom.h>
#include <unistd.h>
#include <time.h>
#include <mach/mach_time.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#include <sys/socketvar.h>
#include <sys/vmmeter.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_var.h>
#include <netinet/tcp_var.h>
#include <netinet/udp_var.h>
#include <CommonCrypto/CommonDigest.h>
#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy)))
#define SHA512_CTX CC_SHA512_CTX
#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
#define REPEAT 5
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define HX(a, b) \
do { \
if ((a)) \
HD(errno); \
else \
HD(b); \
} while (0)
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
int getentropy(void *buf, size_t len);
#ifdef CAN_REFERENCE_MAIN
extern int main(int, char *argv[]);
#endif
static int gotdata(char *buf, size_t len);
static int getentropy_urandom(void *buf, size_t len);
static int getentropy_fallback(void *buf, size_t len);
int
getentropy(void *buf, size_t len)
{
int ret = -1;
if (len > 256) {
goto error;
errno = EIO;
return -1;
}
if (SecRandomCopyBytes(kSecRandomDefault, len, buf) == errSecSuccess) {
return 0;
}
/*
* Try to get entropy with /dev/urandom
*
* This can fail if the process is inside a chroot or if file
* descriptors are exhausted.
*/
ret = getentropy_urandom(buf, len);
if (ret != -1)
return (ret);
error:
/*
* Entropy collection via /dev/urandom and sysctl have failed.
*
* No other API exists for collecting entropy, and we have
* no failsafe way to get it on OSX that is not sensitive
* to resource exhaustion.
*
* We have very few options:
* - Even syslog_r is unsafe to call at this low level, so
* there is no way to alert the user or program.
* - Cannot call abort() because some systems have unsafe
* corefiles.
* - Could raise(SIGKILL) resulting in silent program termination.
* - Return EIO, to hint that arc4random's stir function
* should raise(SIGKILL)
* - Do the best under the circumstances....
*
* This code path exists to bring light to the issue that OSX
* does not provide a failsafe API for entropy collection.
*
* We hope this demonstrates that OSX should consider
* providing a new failsafe API which works in a chroot or
* when file descriptors are exhausted.
*/
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
raise(SIGKILL);
#endif
ret = getentropy_fallback(buf, len);
if (ret != -1)
return (ret);
errno = EIO;
return (ret);
}
/*
* Basic sanity checking; wish we could do better.
*/
static int
gotdata(char *buf, size_t len)
{
char any_set = 0;
size_t i;
for (i = 0; i < len; ++i)
any_set |= buf[i];
if (any_set == 0)
return -1;
return 0;
}
static int
getentropy_urandom(void *buf, size_t len)
{
struct stat st;
size_t i;
int fd, flags;
int save_errno = errno;
start:
flags = O_RDONLY;
#ifdef O_NOFOLLOW
flags |= O_NOFOLLOW;
#endif
#ifdef O_CLOEXEC
flags |= O_CLOEXEC;
#endif
fd = open("/dev/urandom", flags, 0);
if (fd == -1) {
if (errno == EINTR)
goto start;
goto nodevrandom;
}
#ifndef O_CLOEXEC
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#endif
/* Lightly verify that the device node looks sane */
if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
close(fd);
goto nodevrandom;
}
for (i = 0; i < len; ) {
size_t wanted = len - i;
ssize_t ret = read(fd, (char*)buf + i, wanted);
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
continue;
close(fd);
goto nodevrandom;
}
i += ret;
}
close(fd);
if (gotdata(buf, len) == 0) {
errno = save_errno;
return 0; /* satisfied */
}
nodevrandom:
errno = EIO;
return -1;
}
static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
static int kmib[] = { CTL_KERN, KERN_USRSTACK };
static int hwmib[] = { CTL_HW, HW_USERMEM };
static int
getentropy_fallback(void *buf, size_t len)
{
uint8_t results[SHA512_DIGEST_LENGTH];
int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
static int cnt;
struct timespec ts;
struct timeval tv;
struct rusage ru;
sigset_t sigset;
struct stat st;
SHA512_CTX ctx;
static pid_t lastpid;
pid_t pid;
size_t i, ii, m;
char *p;
struct tcpstat tcpstat;
struct udpstat udpstat;
struct ipstat ipstat;
u_int64_t mach_time;
unsigned int idata;
void *addr;
pid = getpid();
if (lastpid == pid) {
faster = 1;
repeat = 2;
} else {
faster = 0;
lastpid = pid;
repeat = REPEAT;
}
for (i = 0; i < len; ) {
int j;
SHA512_Init(&ctx);
for (j = 0; j < repeat; j++) {
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
if (e != -1) {
cnt += (int)tv.tv_sec;
cnt += (int)tv.tv_usec;
}
mach_time = mach_absolute_time();
HD(mach_time);
ii = sizeof(addr);
HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
&addr, &ii, NULL, 0) == -1, addr);
ii = sizeof(idata);
HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
&idata, &ii, NULL, 0) == -1, idata);
ii = sizeof(tcpstat);
HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
&tcpstat, &ii, NULL, 0) == -1, tcpstat);
ii = sizeof(udpstat);
HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
&udpstat, &ii, NULL, 0) == -1, udpstat);
ii = sizeof(ipstat);
HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
&ipstat, &ii, NULL, 0) == -1, ipstat);
HX((pid = getpid()) == -1, pid);
HX((pid = getsid(pid)) == -1, pid);
HX((pid = getppid()) == -1, pid);
HX((pid = getpgid(0)) == -1, pid);
HX((e = getpriority(0, 0)) == -1, e);
if (!faster) {
ts.tv_sec = 0;
ts.tv_nsec = 1;
(void) nanosleep(&ts, NULL);
}
HX(sigpending(&sigset) == -1, sigset);
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
sigset);
#ifdef CAN_REFERENCE_MAIN
HF(main); /* an addr in program */
#endif
HF(getentropy); /* an addr in this library */
HF(printf); /* an addr in libc */
p = (char *)&p;
HD(p); /* an addr on stack */
p = (char *)&errno;
HD(p); /* the addr of errno */
if (i == 0) {
struct sockaddr_storage ss;
struct statvfs stvfs;
struct termios tios;
struct statfs stfs;
socklen_t ssl;
off_t off;
/*
* Prime-sized mappings encourage fragmentation;
* thus exposing some address entropy.
*/
struct mm {
size_t npg;
void *p;
} mm[] = {
{ 17, MAP_FAILED }, { 3, MAP_FAILED },
{ 11, MAP_FAILED }, { 2, MAP_FAILED },
{ 5, MAP_FAILED }, { 3, MAP_FAILED },
{ 7, MAP_FAILED }, { 1, MAP_FAILED },
{ 57, MAP_FAILED }, { 3, MAP_FAILED },
{ 131, MAP_FAILED }, { 1, MAP_FAILED },
};
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
HX(mm[m].p = mmap(NULL,
mm[m].npg * pgs,
PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_ANON, -1,
(off_t)0), mm[m].p);
if (mm[m].p != MAP_FAILED) {
size_t mo;
/* Touch some memory... */
p = mm[m].p;
mo = cnt %
(mm[m].npg * pgs - 1);
p[mo] = 1;
cnt += (int)((long)(mm[m].p)
/ pgs);
}
/* Check cnts and times... */
mach_time = mach_absolute_time();
HD(mach_time);
cnt += (int)mach_time;
HX((e = getrusage(RUSAGE_SELF,
&ru)) == -1, ru);
if (e != -1) {
cnt += (int)ru.ru_utime.tv_sec;
cnt += (int)ru.ru_utime.tv_usec;
}
}
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
if (mm[m].p != MAP_FAILED)
munmap(mm[m].p, mm[m].npg * pgs);
mm[m].p = MAP_FAILED;
}
HX(stat(".", &st) == -1, st);
HX(statvfs(".", &stvfs) == -1, stvfs);
HX(statfs(".", &stfs) == -1, stfs);
HX(stat("/", &st) == -1, st);
HX(statvfs("/", &stvfs) == -1, stvfs);
HX(statfs("/", &stfs) == -1, stfs);
HX((e = fstat(0, &st)) == -1, st);
if (e == -1) {
if (S_ISREG(st.st_mode) ||
S_ISFIFO(st.st_mode) ||
S_ISSOCK(st.st_mode)) {
HX(fstatvfs(0, &stvfs) == -1,
stvfs);
HX(fstatfs(0, &stfs) == -1,
stfs);
HX((off = lseek(0, (off_t)0,
SEEK_CUR)) < 0, off);
}
if (S_ISCHR(st.st_mode)) {
HX(tcgetattr(0, &tios) == -1,
tios);
} else if (S_ISSOCK(st.st_mode)) {
memset(&ss, 0, sizeof ss);
ssl = sizeof(ss);
HX(getpeername(0,
(void *)&ss, &ssl) == -1,
ss);
}
}
HX((e = getrusage(RUSAGE_CHILDREN,
&ru)) == -1, ru);
if (e != -1) {
cnt += (int)ru.ru_utime.tv_sec;
cnt += (int)ru.ru_utime.tv_usec;
}
} else {
/* Subsequent hashes absorb previous result */
HD(results);
}
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
if (e != -1) {
cnt += (int)tv.tv_sec;
cnt += (int)tv.tv_usec;
}
HD(cnt);
}
SHA512_Final(results, &ctx);
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
i += min(sizeof(results), len - i);
}
memset(results, 0, sizeof results);
if (gotdata(buf, len) == 0) {
errno = save_errno;
return 0; /* satisfied */
}
errno = EIO;
return -1;
}
+4 -4
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */
/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */
/*
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
@@ -47,7 +47,7 @@
#define SHA512_Update SHA512Update
#define SHA512_Final SHA512Final
#else
#include <openssl/sha.h>
#include "openssl/sha.h"
#endif
#include <sys/vfs.h>
@@ -204,7 +204,7 @@ start:
}
for (i = 0; i < len; ) {
size_t wanted = len - i;
ssize_t ret = read(fd, (char *)buf + i, wanted);
ssize_t ret = read(fd, (char*)buf + i, wanted);
if (ret == -1) {
if (errno == EAGAIN || errno == EINTR)
@@ -428,7 +428,7 @@ getentropy_fallback(void *buf, size_t len)
HD(cnt);
}
SHA512_Final(results, &ctx);
memcpy((char *)buf + i, results, min(sizeof(results), len - i));
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
i += min(sizeof(results), len - i);
}
memset(results, 0, sizeof results);
+2 -5
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
/* $OpenBSD$ */
/*
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
@@ -15,9 +15,6 @@
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Emulation of getentropy(2) as documented at:
* http://man.openbsd.org/getentropy.2
*/
#include <windows.h>
@@ -40,7 +37,7 @@ getentropy(void *buf, size_t len)
if (len > 256) {
errno = EIO;
return (-1);
return -1;
}
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+4 -1
View File
@@ -42,7 +42,10 @@ static const int year_lengths[2] = {
};
static void
timesub(const time_t * const timep, const long offset, struct tm * const tmp)
timesub(timep, offset, tmp)
const time_t * const timep;
const long offset;
struct tm * const tmp;
{
long days;
long rem;
+10 -3
View File
@@ -59,7 +59,10 @@ static int inet_pton6 (const char *src, uint8_t *dst);
* Paul Vixie, 1996.
*/
int
inet_pton(int af, const char *src, void *dst)
inet_pton(af, src, dst)
int af;
const char *src;
void *dst;
{
switch (af) {
case AF_INET:
@@ -88,7 +91,9 @@ inet_pton(int af, const char *src, void *dst)
* Paul Vixie, 1996.
*/
static int
inet_pton4(const char *src, uint8_t *dst)
inet_pton4(src, dst)
const char *src;
uint8_t *dst;
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
@@ -140,7 +145,9 @@ inet_pton4(const char *src, uint8_t *dst)
* Paul Vixie, 1996.
*/
static int
inet_pton6(const char *src, uint8_t *dst)
inet_pton6(src, dst)
const char *src;
uint8_t *dst;
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
+1 -2
View File
@@ -5,8 +5,7 @@
#undef malloc
#include <sys/types.h>
/* provide a prototype */
void *malloc (size_t n);
void *malloc ();
/* Allocate an N-byte block of memory from the heap.
If N is zero, allocate a 1-byte block. */
+2 -5
View File
@@ -658,7 +658,7 @@ int vsnprintf(char* str, size_t size, const char* format, va_list arg)
* are not their own functions. */
/* printout designation:
* conversion specifier: x, d, u, s, c, m, p
* conversion specifier: x, d, u, s, c, n, m, p
* flags: # not supported
* 0 zeropad (on the left)
* - left adjust (right by default)
@@ -798,10 +798,7 @@ int vsnprintf(char* str, size_t size, const char* format, va_list arg)
minw, minus);
break;
case 'n':
/* unsupported to harden against format string
* exploitation,
* handled like an unknown format specifier. */
/* *va_arg(arg, int*) = ret; */
*va_arg(arg, int*) = ret;
break;
case 'm':
print_str(&at, &left, &ret, strerror(errno),
+673 -1023
View File
File diff suppressed because it is too large Load Diff
+43 -454
View File
@@ -1,8 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* apply the fallthrough attribute. */
#undef ATTR_FALLTHROUGH
/* apply the noreturn attribute to a function that exits the program */
#undef ATTR_NORETURN
@@ -18,9 +15,6 @@
/* Do sha512 definitions in config.h */
#undef COMPAT_SHA512
/* Command line arguments used with configure */
#undef CONFCMDLINE
/* Pathname to the Unbound configuration file */
#undef CONFIGFILE
@@ -31,15 +25,6 @@
/* Whether daemon is deprecated */
#undef DEPRECATED_DAEMON
/* Whether X509_NAME_get_text_by_NID is deprecated */
#undef DEPRECATED_X509_NAME_GET_TEXT_BY_NID
/* Deprecate RSA 1024 bit length, makes that an unsupported key */
#undef DEPRECATE_RSA_1024
/* Define this to enable kernel based UDP source port randomization. */
#undef DISABLE_EXPLICIT_PORT_RANDOMISATION
/* default dnstap socket path */
#undef DNSTAP_SOCKET_PATH
@@ -63,18 +48,9 @@
/* Define to 1 if you have the <arpa/inet.h> header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */
#undef HAVE_ASN1_STRING_GET0_DATA
/* Whether the C compiler accepts the "fallthrough" attribute */
#undef HAVE_ATTR_FALLTHROUGH
/* Whether the C compiler accepts the "format" attribute */
#undef HAVE_ATTR_FORMAT
/* Whether the C compiler accepts the "nonstring" attribute */
#undef HAVE_ATTR_NONSTRING
/* Whether the C compiler accepts the "noreturn" attribute */
#undef HAVE_ATTR_NORETURN
@@ -84,18 +60,6 @@
/* Whether the C compiler accepts the "weak" attribute */
#undef HAVE_ATTR_WEAK
/* If we have be64toh */
#undef HAVE_BE64TOH
/* Define to 1 if you have the `BIO_set_callback_ex' function. */
#undef HAVE_BIO_SET_CALLBACK_EX
/* Define to 1 if you have the <bsd/stdlib.h> header file. */
#undef HAVE_BSD_STDLIB_H
/* Define to 1 if you have the <bsd/string.h> header file. */
#undef HAVE_BSD_STRING_H
/* Define to 1 if you have the `chown' function. */
#undef HAVE_CHOWN
@@ -105,9 +69,6 @@
/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
#undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
/* Define to 1 if you have the `ctime_r' function. */
#undef HAVE_CTIME_R
@@ -122,10 +83,6 @@
if you don't. */
#undef HAVE_DECL_ARC4RANDOM_UNIFORM
/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
you don't. */
#undef HAVE_DECL_EVSIGNAL_ASSIGN
/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
don't. */
#undef HAVE_DECL_INET_NTOP
@@ -134,22 +91,6 @@
don't. */
#undef HAVE_DECL_INET_PTON
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
and to 0 if you don't. */
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_conn_server_new', and to
0 if you don't. */
#undef HAVE_DECL_NGTCP2_CONN_SERVER_NEW
/* Define to 1 if you have the declaration of `ngtcp2_crypto_encrypt_cb', and
to 0 if you don't. */
#undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the declaration of `ngtcp2_crypto_ossl_ctx_new',
and to 0 if you don't. */
#undef HAVE_DECL_NGTCP2_CRYPTO_OSSL_CTX_NEW
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#undef HAVE_DECL_NID_ED25519
@@ -186,10 +127,6 @@
0 if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
/* Define to 1 if you have the declaration of `SSL_CTX_set_tmp_ecdh', and to 0
if you don't. */
#undef HAVE_DECL_SSL_CTX_SET_TMP_ECDH
/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
don't. */
#undef HAVE_DECL_STRLCAT
@@ -220,18 +157,12 @@
/* 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
/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
#undef HAVE_ERR_LOAD_CRYPTO_STRINGS
/* Define to 1 if you have the `event_assign' function. */
#undef HAVE_EVENT_ASSIGN
/* Define to 1 if you have the `event_base_free' function. */
#undef HAVE_EVENT_BASE_FREE
@@ -253,10 +184,6 @@
/* Define to 1 if you have the `EVP_cleanup' function. */
#undef HAVE_EVP_CLEANUP
/* Define to 1 if you have the `EVP_default_properties_is_fips_enabled'
function. */
#undef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED
/* Define to 1 if you have the `EVP_DigestVerify' function. */
#undef HAVE_EVP_DIGESTVERIFY
@@ -266,9 +193,6 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#undef HAVE_EVP_MD_CTX_NEW
@@ -299,12 +223,6 @@
/* Define to 1 if you have the `FIPS_mode' function. */
#undef HAVE_FIPS_MODE
/* Define to 1 if you have the `fnmatch' function. */
#undef HAVE_FNMATCH
/* Define to 1 if you have the <fnmatch.h> header file. */
#undef HAVE_FNMATCH_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
@@ -323,9 +241,6 @@
/* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY
/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
@@ -335,9 +250,6 @@
/* Define to 1 if you have the `getrlimit' function. */
#undef HAVE_GETRLIMIT
/* Define to 1 if you have the `gettid' function. */
#undef HAVE_GETTID
/* Define to 1 if you have the `glob' function. */
#undef HAVE_GLOB
@@ -356,14 +268,8 @@
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX
/* If we have htobe64 */
#undef HAVE_HTOBE64
/* Define to 1 if you have the <ifaddrs.h> header file. */
#undef HAVE_IFADDRS_H
/* Define to 1 if you have the `if_nametoindex' function. */
#undef HAVE_IF_NAMETOINDEX
/* If you have HMAC_Update */
#undef HAVE_HMAC_UPDATE
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
@@ -392,21 +298,12 @@
/* Define to 1 if you have the `kill' function. */
#undef HAVE_KILL
/* Use portable libbsd functions */
#undef HAVE_LIBBSD
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
#undef HAVE_LIBKERN_OSBYTEORDER_H
/* Define if we have LibreSSL */
#undef HAVE_LIBRESSL
/* If we have atomic_store */
#undef HAVE_LINK_ATOMIC_STORE
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
@@ -419,8 +316,8 @@
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
/* Define to 1 if you have the <minix/config.h> header file. */
#undef HAVE_MINIX_CONFIG_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H
@@ -431,9 +328,6 @@
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the <netioapi.h> header file. */
#undef HAVE_NETIOAPI_H
/* Use libnettle for crypto */
#undef HAVE_NETTLE
@@ -443,83 +337,6 @@
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
#undef HAVE_NETTLE_EDDSA_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define to 1 if you have the <net/pfvar.h> header file. */
#undef HAVE_NET_PFVAR_H
/* Define this to use nghttp2 client. */
#undef HAVE_NGHTTP2
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
#undef HAVE_NGHTTP2_NGHTTP2_H
/* Define this to use ngtcp2. */
#undef HAVE_NGTCP2
/* Define to 1 if you have the `ngtcp2_ccerr_default' function. */
#undef HAVE_NGTCP2_CCERR_DEFAULT
/* Define to 1 if you have the `ngtcp2_conn_encode_0rtt_transport_params'
function. */
#undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS
/* Define to 1 if you have the `ngtcp2_conn_get_max_local_streams_uni'
function. */
#undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI
/* Define to 1 if you have the `ngtcp2_conn_get_num_scid' function. */
#undef HAVE_NGTCP2_CONN_GET_NUM_SCID
/* Define to 1 if you have the `ngtcp2_conn_in_closing_period' function. */
#undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD
/* Define to 1 if you have the `ngtcp2_conn_in_draining_period' function. */
#undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD
/* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */
#undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4
/* Define to 1 if you have the `ngtcp2_conn_tls_early_data_rejected' function.
*/
#undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED
/* Define to 1 if you have the `ngtcp2_crypto_encrypt_cb' function. */
#undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_client_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_configure_server_context' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT
/* Define to 1 if you have the
`ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL
/* Define to 1 if you have the `ngtcp2_crypto_quictls_init' function. */
#undef HAVE_NGTCP2_CRYPTO_QUICTLS_INIT
/* Define to 1 if the system has the type `ngtcp2_encryption_level'. */
#undef HAVE_NGTCP2_ENCRYPTION_LEVEL
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_ossl.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_OSSL_H
/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file.
*/
#undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H
/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */
#undef HAVE_NGTCP2_NGTCP2_H
/* Use libnss for crypto */
#undef HAVE_NSS
@@ -529,18 +346,12 @@
/* Define to 1 if you have the <openssl/bn.h> header file. */
#undef HAVE_OPENSSL_BN_H
/* Define to 1 if you have the `OPENSSL_cleanup' function. */
#undef HAVE_OPENSSL_CLEANUP
/* Define to 1 if you have the `OPENSSL_config' function. */
#undef HAVE_OPENSSL_CONFIG
/* 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
@@ -559,9 +370,6 @@
/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
#undef HAVE_OPENSSL_INIT_SSL
/* Define to 1 if you have the <openssl/param_build.h> header file. */
#undef HAVE_OPENSSL_PARAM_BUILD_H
/* Define to 1 if you have the <openssl/rand.h> header file. */
#undef HAVE_OPENSSL_RAND_H
@@ -571,39 +379,15 @@
/* Define to 1 if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
#undef HAVE_OSSL_PARAM_BLD_NEW
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define to 1 if you have the <poll.h> header file. */
#undef HAVE_POLL_H
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the <pthread_np.h> header file. */
#undef HAVE_PTHREAD_NP_H
/* Have PTHREAD_PRIO_INHERIT. */
#undef HAVE_PTHREAD_PRIO_INHERIT
/* Define to 1 if the system has the type `pthread_rwlock_t'. */
#undef HAVE_PTHREAD_RWLOCK_T
/* Define if pthread_setname_np has the common 2 arguments. */
#undef HAVE_PTHREAD_SETNAME_NP
/* Define if pthread_setname_np has only 1 argument. */
#undef HAVE_PTHREAD_SETNAME_NP1
/* Define if pthread_setname_np has 3 arguments. */
#undef HAVE_PTHREAD_SETNAME_NP3
/* Define if pthread_setname_np exists as pthread_set_name_np instead. */
#undef HAVE_PTHREAD_SET_NAME_NP
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
#undef HAVE_PTHREAD_SPINLOCK_T
@@ -619,7 +403,7 @@
/* Define to 1 if you have the `RAND_cleanup' function. */
#undef HAVE_RAND_CLEANUP
/* If we have reallocarray(3) */
/* Define to 1 if you have the `reallocarray' function. */
#undef HAVE_REALLOCARRAY
/* Define to 1 if you have the `recvmsg' function. */
@@ -676,59 +460,30 @@
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the `SSL_CTX_set_alpn_protos' function. */
#undef HAVE_SSL_CTX_SET_ALPN_PROTOS
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
/* 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_evp_cb'
function. */
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
#undef HAVE_SSL_GET0_ALPN_SELECTED
/* 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_get0_peername' function. */
#undef HAVE_SSL_GET0_PEERNAME
/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */
#undef HAVE_SSL_GET1_PEER_CERTIFICATE
/* Define to 1 if you have the `SSL_is_quic' function. */
#undef HAVE_SSL_IS_QUIC
/* Define to 1 if you have the `SSL_set1_dnsname' function. */
#undef HAVE_SSL_SET1_DNSNAME
/* Define to 1 if you have the `SSL_set1_host' function. */
#undef HAVE_SSL_SET1_HOST
/* Define to 1 if you have the `SSL_set_quic_tls_early_data_enabled' function.
*/
#undef HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the <stdatomic.h> header file. */
#undef HAVE_STDATOMIC_H
/* Define to 1 if you have the <stdbool.h> header file. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdio.h> header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
@@ -756,32 +511,9 @@
/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
#undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_pkt_hd'. */
#undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN
/* Define to 1 if `max_tx_udp_payload_size' is a member of `struct
ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE
/* Define to 1 if `tokenlen' is a member of `struct ngtcp2_settings'. */
#undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN
/* Define to 1 if `original_dcid_present' is a member of `struct
ngtcp2_transport_params'. */
#undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT
/* Define to 1 if the system has the type `struct ngtcp2_version_cid'. */
#undef HAVE_STRUCT_NGTCP2_VERSION_CID
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
/* Define if you have Swig libraries and header files. */
#undef HAVE_SWIG
@@ -803,9 +535,6 @@
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/sha2.h> header file. */
#undef HAVE_SYS_SHA2_H
@@ -833,9 +562,6 @@
/* 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
@@ -854,9 +580,6 @@
/* Define to 1 if you have the <vfork.h> header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the <wchar.h> header file. */
#undef HAVE_WCHAR_H
/* Define to 1 if you have the <windows.h> header file. */
#undef HAVE_WINDOWS_H
@@ -878,21 +601,12 @@
/* Define to 1 if you have the <ws2tcpip.h> header file. */
#undef HAVE_WS2TCPIP_H
/* Define to 1 if you have the `X509_get_key_usage' function. */
#undef HAVE_X509_GET_KEY_USAGE
/* Define to 1 if you have the `X509_NAME_get_text_by_NID' function. */
#undef HAVE_X509_NAME_GET_TEXT_BY_NID
/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
/* Define to 1 if you have the `_beginthreadex' function. */
#undef HAVE__BEGINTHREADEX
/* If HMAC_Init_ex() returns void */
#undef HMAC_INIT_EX_RETURNS_VOID
/* if lex has yylex_destroy */
#undef LEX_HAS_YYLEX_DESTROY
@@ -964,8 +678,7 @@
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Return type of signal handlers, but autoconf 2.70 says 'your code may
safely assume C89 semantics that RETSIGTYPE is void.' */
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* if REUSEPORT is enabled by default */
@@ -986,27 +699,16 @@
/* Shared data */
#undef SHARE_DIR
/* The size of `pthread_t', as computed by sizeof. */
#undef SIZEOF_PTHREAD_T
/* The size of `size_t', as computed by sizeof. */
#undef SIZEOF_SIZE_T
/* The size of `time_t', as computed by sizeof. */
#undef SIZEOF_TIME_T
/* The size of `unsigned long', as computed by sizeof. */
#undef SIZEOF_UNSIGNED_LONG
/* define if (v)snprintf does not return length needed, (but length used) */
#undef SNPRINTF_RET_BROKEN
/* Define to 1 if libsodium supports sodium_set_misuse_handler */
#undef SODIUM_MISUSE_HANDLER
/* Define to 1 if all of the C90 standard headers exist (not just the ones
required in a freestanding environment). This macro is provided for
backward compatibility; new code need not use it. */
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* use default strptime. */
@@ -1015,9 +717,6 @@
/* Use win32 resources and API */
#undef UB_ON_WINDOWS
/* the SYSLOG_FACILITY to use, default LOG_DAEMON */
#undef UB_SYSLOG_FACILITY
/* default username */
#undef UB_USERNAME
@@ -1066,29 +765,12 @@
/* Define to 1 to use ipsecmod support. */
#undef USE_IPSECMOD
/* Define to 1 to use ipset support */
#undef USE_IPSET
/* Define if you enable libevent */
#undef USE_LIBEVENT
/* Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a
default outgoing port range. This is only for the libunbound on Linux and
does not affect unbound resolving daemon itself. This may severely limit
the number of available outgoing ports and thus decrease randomness. Define
this only when the target system restricts (e.g. some of SELinux enabled
distributions) the use of non-ephemeral ports. */
#undef USE_LINUX_IP_LOCAL_PORT_RANGE
/* Define if you want to use internal select based events */
#undef USE_MINI_EVENT
/* Define this to enable client TCP Fast Open. */
#undef USE_MSG_FASTOPEN
/* Define this to use ngtcp2_crypto_ossl. */
#undef USE_NGTCP2_CRYPTO_OSSL
/* Define this to enable client TCP Fast Open. */
#undef USE_OSX_MSG_FASTOPEN
@@ -1105,87 +787,21 @@
#ifndef _ALL_SOURCE
# undef _ALL_SOURCE
#endif
/* Enable general extensions on macOS. */
#ifndef _DARWIN_C_SOURCE
# undef _DARWIN_C_SOURCE
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# undef _GNU_SOURCE
#endif
/* Enable X/Open compliant socket functions that do not require linking
with -lxnet on HP-UX 11.11. */
#ifndef _HPUX_ALT_XOPEN_SOCKET_API
# undef _HPUX_ALT_XOPEN_SOCKET_API
#endif
/* Identify the host operating system as Minix.
This macro does not affect the system headers' behavior.
A future release of Autoconf may stop defining this macro. */
#ifndef _MINIX
# undef _MINIX
#endif
/* Enable general extensions on NetBSD.
Enable NetBSD compatibility extensions on Minix. */
#ifndef _NETBSD_SOURCE
# undef _NETBSD_SOURCE
#endif
/* Enable OpenBSD compatibility extensions on NetBSD.
Oddly enough, this does nothing on OpenBSD. */
#ifndef _OPENBSD_SOURCE
# undef _OPENBSD_SOURCE
#endif
/* Define to 1 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_SOURCE
# undef _POSIX_SOURCE
#endif
/* Define to 2 if needed for POSIX-compatible behavior. */
#ifndef _POSIX_1_SOURCE
# undef _POSIX_1_SOURCE
#endif
/* Enable POSIX-compatible threading on Solaris. */
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */
#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */
#ifndef __STDC_WANT_IEC_60559_BFP_EXT__
# undef __STDC_WANT_IEC_60559_BFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */
#ifndef __STDC_WANT_IEC_60559_DFP_EXT__
# undef __STDC_WANT_IEC_60559_DFP_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */
#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__
# undef __STDC_WANT_IEC_60559_FUNCS_EXT__
#endif
/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */
#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
# undef __STDC_WANT_IEC_60559_TYPES_EXT__
#endif
/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */
#ifndef __STDC_WANT_LIB_EXT2__
# undef __STDC_WANT_LIB_EXT2__
#endif
/* Enable extensions specified by ISO/IEC 24747:2009. */
#ifndef __STDC_WANT_MATH_SPEC_FUNCS__
# undef __STDC_WANT_MATH_SPEC_FUNCS__
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif
/* Enable X/Open extensions. Define to 500 only if necessary
to make mbstate_t available. */
#ifndef _XOPEN_SOURCE
# undef _XOPEN_SOURCE
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
@@ -1198,9 +814,6 @@
/* 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
@@ -1211,6 +824,11 @@
`char[]'. */
#undef YYTEXT_POINTER
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
@@ -1220,12 +838,18 @@
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to 1 if on MINIX. */
#undef _MINIX
/* Enable for compile on Minix */
#undef _NETBSD_SOURCE
/* defined to use gcc ansi snprintf and sscanf that understands %lld when
compiled for windows. */
#undef __USE_MINGW_ANSI_STDIO
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
#undef _POSIX_1_SOURCE
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
@@ -1263,7 +887,7 @@
/* Define to `long int' if <sys/types.h> does not define. */
#undef off_t
/* Define as a signed integer type capable of holding a process identifier. */
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to 'int' if not defined */
@@ -1301,51 +925,45 @@
#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
#define _BSD_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE)
#define _DEFAULT_SOURCE 1
#endif
#endif
#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
#define __EXTENSIONS__ 1
#endif
#endif
#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 200112
#endif
#endif
#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE 600
#endif
#endif
#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
#define _XOPEN_SOURCE_EXTENDED 1
#endif
#endif
#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
#define _ALL_SOURCE 1
#endif
#endif
#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
#define _LARGEFILE_SOURCE 1
#endif
#endif
#ifndef _OPENBSD_SOURCE
#define _OPENBSD_SOURCE 1
#endif
#ifndef UNBOUND_DEBUG
# ifndef NDEBUG
# define NDEBUG
# endif
#endif
/** Use small-ldns codebase */
@@ -1406,7 +1024,7 @@
#include <ws2tcpip.h>
#endif
#if !defined(USE_WINSOCK) || !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN) || defined(__USE_MINGW_ANSI_STDIO)
#ifndef USE_WINSOCK
#define ARG_LL "%ll"
#else
#define ARG_LL "%I64"
@@ -1417,7 +1035,7 @@
#endif
#ifdef HAVE_ATTR_FORMAT
# define ATTR_FORMAT(archetype, string_index, first_to_check) \
__attribute__ ((format (archetype, string_index, first_to_check)))
@@ -1437,17 +1055,6 @@
#endif /* !HAVE_ATTR_UNUSED */
#if defined(DOXYGEN)
# define ATTR_NONSTRING(x) x
#elif defined(__cplusplus)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#elif defined(HAVE_ATTR_NONSTRING)
# define ATTR_NONSTRING(x) __attribute__((nonstring)) x
#else /* !HAVE_ATTR_NONSTRING */
# define ATTR_NONSTRING(x) x
#endif /* !HAVE_ATTR_NONSTRING */
#ifndef HAVE_FSEEKO
#define fseeko fseek
#define ftello ftell
@@ -1538,7 +1145,7 @@ void* reallocarray(void *ptr, size_t nmemb, size_t size);
#ifdef HAVE_WINSOCK2_H
#define FD_SET_T (u_int)
#else
#define FD_SET_T
#define FD_SET_T
#endif
@@ -1589,15 +1196,6 @@ struct tm;
char *strptime(const char *s, const char *format, struct tm *tm);
#endif
#if !HAVE_DECL_REALLOCARRAY
void *reallocarray(void *ptr, size_t nmemb, size_t size);
#endif
#ifdef HAVE_LIBBSD
#include <bsd/string.h>
#include <bsd/stdlib.h>
#endif
#ifdef HAVE_LIBRESSL
# if !HAVE_DECL_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
@@ -1611,6 +1209,9 @@ uint32_t arc4random(void);
# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
uint32_t arc4random_uniform(uint32_t upper_bound);
# endif
# if !HAVE_DECL_REALLOCARRAY
void *reallocarray(void *ptr, size_t nmemb, size_t size);
# endif
#endif /* HAVE_LIBRESSL */
#ifndef HAVE_ARC4RANDOM
int getentropy(void* buf, size_t len);
@@ -1666,10 +1267,6 @@ struct sockaddr_storage;
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
#ifdef HAVE_REALLOCARRAY
# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__)
#endif
void *unbound_stat_malloc(size_t size);
void *unbound_stat_calloc(size_t nmemb, size_t size);
void unbound_stat_free(void *ptr);
@@ -1682,10 +1279,6 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
const char* func);
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
int line, const char* func);
void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size,
const char* file, int line, const char* func);
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
const char* func);
#elif defined(UNBOUND_ALLOC_LITE)
# include "util/alloc.h"
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
@@ -1694,10 +1287,6 @@ char *unbound_stat_strdup_log(const char *s, const char* file, int line,
#define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for DNS over QUIC traffic. */
#define UNBOUND_DNS_OVER_QUIC_PORT 853
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953
Vendored
+1425 -1573
View File
File diff suppressed because it is too large Load Diff
Vendored
+5662 -10241
View File
File diff suppressed because it is too large Load Diff
+203 -906
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -1,9 +0,0 @@
FROM gcc:latest
WORKDIR /usr/src/unbound
# install semantic parser & lexical analyzer
# install packages used in tests
RUN apt-get update && apt-get install -y bison flex ldnsutils dnsutils xxd splint doxygen netcat-openbsd
# accept short rsa keys, which are used in tests
RUN sed -i 's/SECLEVEL=2/SECLEVEL=1/g' /usr/lib/ssl/openssl.cnf
CMD ["/bin/bash"]
+1 -21
View File
@@ -27,12 +27,10 @@ distribution but may be helpful.
works like the BIND feature (removes AAAA records unless AAAA-only domain).
Useful for certain 'broken IPv6 default route' scenarios.
Patch from Stephane Lapie for ASAHI Net.
* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
Contributed by Yuri Voinov.
* unbound.socket and unbound.service: systemd files for unbound, install them
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
* unbound_portable.service.in: systemd file for use unbound as portable service,
see comments in the file. Contributed by Frzk.
* redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
instead of SERVFAIL. Contributed by SIDN.
* fastrpz.patch: fastrpz support from Farsight Security.
@@ -42,21 +40,3 @@ distribution but may be helpful.
redis backend) redis Python modules.
* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from
stdin. Used with fuzzers, patch from Jacob Hoffman-Andrews.
* unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
replacements for unbound-fuzzme.c that gets created after applying
the contrib/unbound-fuzzme.patch. They are contributed by
Eric Sesterhenn from X41 D-Sec.
* drop-tld.diff: adds option drop-tld: yesno that drops 2 label queries,
to stop random floods. Apply with patch -p1 < contrib/drop-tld.diff and
compile. From Saksham Manchanda (Secure64). Please note that we think
this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
lookups for downstream clients.
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
contributed by Andreas Schulze.
* metrics.awk: awk script that can convert unbound-control stats to
Prometheus metrics format output.
* unbound.init_yocto: An init script to start and stop the server. Put it
in /etc/init.d/unbound to use it. It is for the Yocto Project, in
embedded systems, contributed by beni-sandu.
* gost12.patch: adds ECC-GOST12 support for the informational RFC9558.
Contributed by Igor V. Ruzanov.
+111 -111
View File
@@ -1,10 +1,10 @@
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index 172eb26c..2921c87f 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -2146,6 +2146,13 @@ Default: no
.UNINDENT
.INDENT 0.0
Index: trunk/doc/unbound.conf.5.in
===================================================================
--- trunk/doc/unbound.conf.5.in (revision 4357)
+++ trunk/doc/unbound.conf.5.in (working copy)
@@ -701,6 +701,13 @@
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.
.TP
+.B aaaa\-filter: \fI<yes or no>
+Activate behavior similar to BIND's AAAA-filter.
@@ -13,18 +13,17 @@ index 172eb26c..2921c87f 100644
+This also causes an additional A query to be sent for each AAAA query.
+This breaks DNSSEC!
+.TP
.B aggressive\-nsec: \fI<yes or no>\fP
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN and other
denials, using information from previous NXDOMAINs answers.
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
index 49a5f5da..fbe434fa 100644
--- a/iterator/iter_scrub.c
+++ b/iterator/iter_scrub.c
@@ -849,6 +849,32 @@ scrub_sanitize_rr_length(sldns_buffer* pkt, struct msg_parse* msg,
return 0;
.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
Index: trunk/iterator/iter_scrub.c
===================================================================
--- trunk/iterator/iter_scrub.c (revision 4357)
+++ trunk/iterator/iter_scrub.c (working copy)
@@ -617,6 +617,32 @@
}
+/**
/**
+ * ASN: Lookup A records from rrset cache.
+ * @param qinfo: the question originally asked.
+ * @param env: module environment with config and cache.
@@ -50,18 +49,19 @@ index 49a5f5da..fbe434fa 100644
+ return 0;
+}
+
/**
+/**
* Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects
@@ -869,6 +895,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
* the response to be in a "normalized" state -- that is, all "irrelevant"
@@ -635,6 +661,7 @@
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie, struct module_qstate* qstate)
struct iter_env* ie)
{
+ int found_a_record = 0; /* ASN: do we have a A record? */
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
uint8_t* ns_rrset_dname = NULL;
@@ -906,6 +933,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
struct rrset_parse* rrset, *prev;
@@ -670,6 +697,13 @@
rrset = rrset->rrset_all_next;
}
@@ -75,10 +75,11 @@ index 49a5f5da..fbe434fa 100644
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
@@ -925,6 +959,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
continue;
}
@@ -680,6 +714,24 @@
prev = NULL;
rrset = msg->rrset_first;
while(rrset) {
+
+ /* ASN: For AAAA records only... */
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
+ /* ASN: If this is not a AAAA query, then remove AAAA
@@ -96,36 +97,35 @@ index 49a5f5da..fbe434fa 100644
+ LDNS_RR_TYPE_AAAA, qinfo->qclass);
+ }
+ /* ASN: End of added code */
+
/* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA)) {
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 1da21896..6583dd0e 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -250,6 +250,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
Index: trunk/iterator/iter_utils.c
===================================================================
--- trunk/iterator/iter_utils.c (revision 4357)
+++ trunk/iterator/iter_utils.c (working copy)
@@ -175,6 +175,7 @@
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
+ iter_env->aaaa_filter = cfg->aaaa_filter;
return 1;
}
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 71e64655..735f4ca0 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -2412,6 +2412,53 @@ check_waiting_queries(struct iter_qstate* iq, struct module_qstate* qstate,
qstate->ext_state[id] = module_wait_reply;
}
Index: trunk/iterator/iterator.c
===================================================================
--- trunk/iterator/iterator.c (revision 4357)
+++ trunk/iterator/iterator.c (working copy)
@@ -1847,6 +1847,53 @@
return 0;
}
+
+/**
+ * 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 71e64655..735f4ca0 100644
+
+ /* 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, 0)) {
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) {
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
+ "preloading of A record for",
+ iq->qchase.qname, LDNS_RR_TYPE_A,
@@ -170,8 +170,8 @@ index 71e64655..735f4ca0 100644
/**
* This is the request event state where the request will be sent to one of
@@ -2554,6 +2601,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
@@ -1894,6 +1941,13 @@
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
+ /* ASN: If we have a AAAA query, then also query for A records */
@@ -184,11 +184,11 @@ index 71e64655..735f4ca0 100644
/* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */
if(!iq->dp) {
@@ -4178,6 +4232,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -3095,6 +3149,61 @@
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.
@@ -236,7 +236,7 @@ index 71e64655..735f4ca0 100644
+ /* see if the failure did get (parent-lame) info */
+ if(!cache_fill_missing(super->env,
+ super_iq->qchase.qclass, super->region,
+ super_iq->dp, 0))
+ super_iq->dp))
+ log_err("ASN-AAAA-filter: out of memory adding missing");
+ dpns->resolved = 1; /* mark as failed */
+ }
@@ -246,7 +246,7 @@ index 71e64655..735f4ca0 100644
/*
* Return priming query results to interested super querystates.
*
@@ -4197,6 +4306,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
@@ -3114,6 +3223,9 @@
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super);
@@ -256,7 +256,7 @@ index 71e64655..735f4ca0 100644
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super);
else if(qstate->is_priming)
@@ -4234,6 +4346,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -3151,6 +3263,9 @@
case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id);
break;
@@ -266,7 +266,7 @@ index 71e64655..735f4ca0 100644
case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id);
break;
@@ -4578,6 +4693,8 @@ iter_state_to_string(enum iter_state state)
@@ -3460,6 +3575,8 @@
return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)";
@@ -275,7 +275,7 @@ index 71e64655..735f4ca0 100644
case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE";
case PRIME_RESP_STATE :
@@ -4602,6 +4719,7 @@ iter_state_is_responsestate(enum iter_state s)
@@ -3484,6 +3601,7 @@
case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE :
@@ -283,11 +283,11 @@ index 71e64655..735f4ca0 100644
case QUERYTARGETS_STATE :
case COLLECT_CLASS_STATE :
return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h
index ae4b4e45..a44f9d27 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -157,6 +157,9 @@ struct iter_env {
Index: trunk/iterator/iterator.h
===================================================================
--- trunk/iterator/iterator.h (revision 4357)
+++ trunk/iterator/iterator.h (working copy)
@@ -130,6 +130,9 @@
*/
int* target_fetch_policy;
@@ -297,11 +297,10 @@ index ae4b4e45..a44f9d27 100644
/** lock on ratelimit counter */
lock_basic_type queries_ratelimit_lock;
/** number of queries that have been ratelimited */
@@ -217,6 +220,14 @@ enum iter_state {
*/
@@ -182,6 +185,14 @@
INIT_REQUEST_3_STATE,
+ /**
/**
+ * This state is responsible for intercepting AAAA queries,
+ * and launch a A subquery on the same target, to populate the
+ * cache with A records, so the AAAA filter scrubbing logic can
@@ -309,28 +308,29 @@ index ae4b4e45..a44f9d27 100644
+ */
+ ASN_FETCH_A_FOR_AAAA_STATE,
+
/**
+ /**
* Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited.
@@ -434,6 +445,13 @@ struct iter_qstate {
* already so that it is accepted later. */
int empty_nodata_found;
* This state is responsible for iterating through a list of
@@ -364,6 +375,13 @@
* be used when creating the state. A higher one will be attempted.
*/
int refetch_glue;
+
+ /**
+ * ASN: This is a flag that, if true, means that this query is
+ * for fetching A records to populate cache and determine if we must
+ * return AAAA records or not.
+ */
+ int fetch_a_for_aaaa;
+
/** list of pending queries to authoritative servers. */
struct outbound_list outlist;
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index 2040fb9e..f073c3dc 100644
--- a/pythonmod/interface.i
+++ b/pythonmod/interface.i
@@ -1013,6 +1013,7 @@ struct config_file {
Index: trunk/pythonmod/interface.i
===================================================================
--- trunk/pythonmod/interface.i (revision 4357)
+++ trunk/pythonmod/interface.i (working copy)
@@ -851,6 +851,7 @@
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
@@ -338,24 +338,24 @@ index 2040fb9e..f073c3dc 100644
struct config_strlist* private_address;
struct config_strlist* private_domain;
size_t unwanted_threshold;
diff --git a/util/config_file.c b/util/config_file.c
index b1e767b3..5eb3c099 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -247,6 +247,7 @@ config_create(void)
Index: trunk/util/config_file.c
===================================================================
--- trunk/util/config_file.c (revision 4357)
+++ trunk/util/config_file.c (working copy)
@@ -195,6 +195,7 @@
cfg->harden_referral_path = 0;
cfg->harden_algo_downgrade = 0;
cfg->harden_unknown_additional = 0;
cfg->use_caps_bits_for_id = 0;
+ cfg->aaaa_filter = 0; /* ASN: default is disabled */
cfg->caps_whitelist = NULL;
cfg->private_address = NULL;
cfg->private_domain = NULL;
diff --git a/util/config_file.h b/util/config_file.h
index 44ac036b..1e59ab07 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -311,6 +311,8 @@ struct config_file {
int harden_unknown_additional;
Index: trunk/util/config_file.h
===================================================================
--- trunk/util/config_file.h (revision 4357)
+++ trunk/util/config_file.h (working copy)
@@ -209,6 +209,8 @@
int harden_algo_downgrade;
/** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id;
+ /** ASN: enable AAAA filter? */
@@ -363,42 +363,44 @@ index 44ac036b..1e59ab07 100644
/** 0x20 whitelist, domains that do not use capsforid */
struct config_strlist* caps_whitelist;
/** strip away these private addrs from answers, no DNS Rebinding */
diff --git a/util/configlexer.lex b/util/configlexer.lex
index bc258673..76aab170 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -327,6 +327,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
Index: trunk/util/configlexer.lex
===================================================================
--- trunk/util/configlexer.lex (revision 4357)
+++ trunk/util/configlexer.lex (working copy)
@@ -279,6 +279,7 @@
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
+aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) }
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
diff --git a/util/configparser.y b/util/configparser.y
index 82e1d878..dc19bed5 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -100,6 +100,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
Index: trunk/util/configparser.y
===================================================================
--- trunk/util/configparser.y (revision 4357)
+++ trunk/util/configparser.y (working copy)
@@ -95,6 +95,7 @@
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
+%token VAR_AAAA_FILTER
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -276,6 +277,7 @@ content_server: server_num_threads | server_verbosity | server_port |
@@ -203,6 +204,7 @@
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics |
server_private_domain | server_extended_statistics |
+ server_aaaa_filter |
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
@@ -1932,6 +1934,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
@@ -1183,6 +1185,15 @@
OUTYY(("P(server_caps_whitelist:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
yyerror("out of memory");
}
;
+ }
+ ;
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
+ {
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
@@ -406,8 +408,6 @@ index 82e1d878..dc19bed5 100644
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
}
;
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
{
OUTYY(("P(server_private_address:%s)\n", $2));
-37
View File
@@ -1,37 +0,0 @@
#### 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",
},
);
-54
View File
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
LIBEXPAT_FNAME=expat-2.7.0
LIBEXPAT_VERSION_DIR=R_2_7_0
echo "Downloading Expat"
if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./$LIBEXPAT_FNAME
if ! tar -xf $LIBEXPAT_FNAME.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd $LIBEXPAT_FNAME || 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
View File
@@ -1,60 +0,0 @@
#!/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
View File
@@ -1,44 +0,0 @@
#!/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
View File
@@ -1,6 +0,0 @@
#!/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
View File
@@ -1,203 +0,0 @@
#!/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 -5
View File
@@ -9,13 +9,12 @@
# Variables
dst_dir="/etc/opt/csw/unbound"
work_dir="/tmp"
list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
# OS commands
CAT=`which cat`
ECHO=`which echo`
WGET=`which wget`
TR=`which tr`
# Check Wget installed
if [ ! -f $WGET ]; then
@@ -23,10 +22,8 @@ if [ ! -f $WGET ]; then
exit 1
fi
# remove special characters with tr to protect unbound.conf
$WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \
$CAT $work_dir/yoyo_ad_servers | \
$TR -d '";$\\' | \
while read line ; \
do \
$ECHO "local-zone: \"$line\" redirect" ;\
@@ -39,4 +36,4 @@ echo "Done."
# the unbound_ad_servers file:
#
# include: $dst_dir/unbound_ad_servers
#
#
-82
View File
@@ -1,82 +0,0 @@
diff --git a/daemon/worker.c b/daemon/worker.c
index 263fcdd..f787b70 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -1213,6 +1213,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
}
+
+ if(worker->env.cfg->drop_tld) {
+ int lab = dname_count_labels(qinfo.qname);
+ if (lab == 2) {
+ comm_point_drop_reply(repinfo);
+ verbose(VERB_ALGO, "Dropping one label query.");
+ return 0;
+ }
+ }
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
verbose(VERB_ALGO, "worker request: refused zone transfer.");
diff --git a/util/config_file.h b/util/config_file.h
index b3ef930..2791541 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -274,6 +274,8 @@ struct config_file {
int prefetch_key;
/** deny queries of type ANY with an empty answer */
int deny_any;
+ /** Drop TLD queries from clients **/
+ int drop_tld;
/** chrootdir, if not "" or chroot will be done */
char* chrootdir;
diff --git a/util/configlexer.lex b/util/configlexer.lex
index a86ddf5..9bbedbb 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -299,6 +299,7 @@ private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
prefetch{COLON} { YDVAR(1, VAR_PREFETCH) }
deny-any{COLON} { YDVAR(1, VAR_DENY_ANY) }
+drop-tld{COLON} { YDVAR(1, VAR_DROP_TLD) }
stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) }
name{COLON} { YDVAR(1, VAR_NAME) }
stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
diff --git a/util/configparser.y b/util/configparser.y
index 10227a2..567d68e 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -164,6 +164,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
+%token VAR_DROP_TLD
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
%token VAR_TLS_SESSION_TICKET_KEYS
@@ -266,6 +267,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
server_tcp_connection_limit | server_log_servfail | server_deny_any |
+ server_drop_tld |
server_unknown_server_time_limit | server_log_tag_queryreply |
server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys
@@ -1466,6 +1468,16 @@ server_deny_any: VAR_DENY_ANY STRING_ARG
free($2);
}
;
+
+server_drop_tld: VAR_DROP_TLD STRING_ARG
+ {
+ OUTYY(("P(server_drop_tld:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->drop_tld = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
{
OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
-39
View File
@@ -1,39 +0,0 @@
#!/usr/bin/perl
# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
#
# unbound.conf:
# rpz:
# name: "drop.spamhaus.org.rpz.local."
# zonefile: "/path/tp/spamhaus-drop.rpz.local"
# rpz-log: yes
# rpz-log-name: "spamhaus-drop"
#
use strict;
use vars qw{$o1 $o2 $o3 $o4 $m};
# trailing dots required
my $origin = 'drop.spamhaus.org.rpz.local.';
my $mname = 'localhost.';
my $rname = 'root.localhost.';
my $ns = $mname;
my $rpz_action = '.'; # return NXDOMAIN
#my $rpz_action = '*.'; # return NODATA
#my $rpz_action = 'rpz-drop.'; # drop the query
print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
print "$origin NS $ns\n";
while(<>) {
if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
} else {
print "$_";
}
}
# add a testpoint: ask for "dns.google"
# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
exit;
+182 -185
View File
@@ -1,11 +1,11 @@
Description: based on the included patch contrib/fastrpz.patch
Author: fastrpz@farsightsecurity.com
---
diff --git a/Makefile.in b/Makefile.in
index bac212df..4824927f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
Index: unboundfastrpz/Makefile.in
===================================================================
--- unboundfastrpz/Makefile.in (revision 5073)
+++ unboundfastrpz/Makefile.in (working copy)
@@ -23,6 +23,8 @@
CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
DNSTAP_SRC=@DNSTAP_SRC@
DNSTAP_OBJ=@DNSTAP_OBJ@
@@ -13,26 +13,26 @@ index bac212df..4824927f 100644
+FASTRPZ_OBJ=@FASTRPZ_OBJ@
DNSCRYPT_SRC=@DNSCRYPT_SRC@
DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
WITH_DYNLIBMODULE=@WITH_DYNLIBMODULE@
@@ -134,7 +136,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
@@ -126,7 +128,7 @@
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) \
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
+$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC)
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 \
@@ -147,7 +149,7 @@ autotrust.lo val_anchor.lo rpz.lo \
@@ -139,7 +141,7 @@
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) $(DYNLIBMOD_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo
-$(IPSECMOD_OBJ) respip.lo
+$(FASTRPZ_OBJ) $(IPSECMOD_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
@@ -428,6 +430,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
@@ -405,6 +407,11 @@
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
$(srcdir)/util/netevent.h
@@ -44,11 +44,11 @@ index bac212df..4824927f 100644
# Python Module
pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
pythonmod/interface.h \
diff --git a/config.h.in b/config.h.in
index f7a4095e..d5a4fa01 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1364,4 +1364,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
Index: unboundfastrpz/config.h.in
===================================================================
--- unboundfastrpz/config.h.in (revision 5073)
+++ unboundfastrpz/config.h.in (working copy)
@@ -1293,4 +1293,11 @@
/** the version of unbound-control that this software implements */
#define UNBOUND_CONTROL_VERSION 1
@@ -61,11 +61,11 @@ index f7a4095e..d5a4fa01 100644
+#undef FASTRPZ_LIB_OPEN
+/** turn on fastrpz response policy zones */
+#undef ENABLE_FASTRPZ
diff --git a/configure.ac b/configure.ac
index 5c373d9d..e45abd89 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
Index: unboundfastrpz/configure.ac
===================================================================
--- unboundfastrpz/configure.ac (revision 5073)
+++ unboundfastrpz/configure.ac (working copy)
@@ -6,6 +6,7 @@
sinclude(acx_python.m4)
sinclude(ac_pkg_swig.m4)
sinclude(dnstap/dnstap.m4)
@@ -73,20 +73,20 @@ index 5c373d9d..e45abd89 100644
sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
@@ -1819,6 +1820,9 @@ case "$enable_explicit_port_randomisation" in
@@ -1575,6 +1576,9 @@
;;
esac
+# check for Fastrpz with fastrpz/rpz.m4
+ck_FASTRPZ
+
AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
# 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 5d427925..f89f1437 100644
--- a/daemon/daemon.c
+++ b/daemon/daemon.c
Index: unboundfastrpz/daemon/daemon.c
===================================================================
--- unboundfastrpz/daemon/daemon.c (revision 5073)
+++ unboundfastrpz/daemon/daemon.c (working copy)
@@ -91,6 +91,9 @@
#include "sldns/keyraw.h"
#include "respip/respip.h"
@@ -97,36 +97,36 @@ index 5d427925..f89f1437 100644
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
@@ -456,6 +459,14 @@ daemon_create_workers(struct daemon* daemon)
fatal_exit("dt_create failed");
#else
@@ -462,6 +465,14 @@
fatal_exit("dnstap enabled in config but not built with dnstap support");
+#endif
+ }
#endif
}
+ if(daemon->cfg->rpz_enable) {
+#ifdef ENABLE_FASTRPZ
+ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
+#else
+ fatal_exit("fastrpz enabled in config"
+ " but not built with fastrpz");
#endif
}
+#endif
+ }
for(i=0; i<daemon->num; i++) {
@@ -729,6 +740,9 @@ daemon_cleanup(struct daemon* daemon)
#ifdef USE_DNSCRYPT
if(!(daemon->workers[i] = worker_create(daemon, i,
shufport+numport*i/daemon->num,
@@ -719,6 +730,9 @@
dnsc_delete(daemon->dnscenv);
daemon->dnscenv = NULL;
+#endif
#endif
+#ifdef ENABLE_FASTRPZ
+ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
#endif
+#endif
daemon->cfg = NULL;
}
diff --git a/daemon/daemon.h b/daemon/daemon.h
index 3effbafb..4d4c34da 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -138,6 +138,11 @@ struct daemon {
Index: unboundfastrpz/daemon/daemon.h
===================================================================
--- unboundfastrpz/daemon/daemon.h (revision 5073)
+++ unboundfastrpz/daemon/daemon.h (working copy)
@@ -136,6 +136,11 @@
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
@@ -138,11 +138,11 @@ index 3effbafb..4d4c34da 100644
};
/**
diff --git a/daemon/worker.c b/daemon/worker.c
index 23e3244c..b63d49b7 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -76,6 +76,9 @@
Index: unboundfastrpz/daemon/worker.c
===================================================================
--- unboundfastrpz/daemon/worker.c (revision 5073)
+++ unboundfastrpz/daemon/worker.c (working copy)
@@ -75,6 +75,9 @@
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/sbuffer.h"
@@ -152,7 +152,7 @@ index 23e3244c..b63d49b7 100644
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
@@ -535,8 +538,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
@@ -533,8 +536,27 @@
/* not secure */
secure = 0;
break;
@@ -180,10 +180,10 @@ index 23e3244c..b63d49b7 100644
/* return this delegation from the cache */
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -711,6 +733,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
*is_secure_answer = 0;
@@ -702,6 +724,23 @@
secure = 0;
}
} else *is_secure_answer = 0;
} else secure = 0;
+#ifdef ENABLE_FASTRPZ
+ if(repinfo->rpz) {
+ /* Scan the cached answer for RPZ hits.
@@ -204,7 +204,7 @@ index 23e3244c..b63d49b7 100644
edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
@@ -1436,6 +1475,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
@@ -1407,6 +1446,15 @@
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen);
goto send_reply;
@@ -220,14 +220,14 @@ index 23e3244c..b63d49b7 100644
}
/* If we've found a local alias, replace the qname with the alias
@@ -1486,12 +1534,21 @@ lookup_cache:
@@ -1455,12 +1503,21 @@
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 */
- if(answer_from_cache(worker, &qinfo,
+ ret = answer_from_cache(worker, &qinfo,
cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
&alias_rrset, &partial_rep, (struct reply_info*)e->data,
cinfo, &need_drop, &alias_rrset, &partial_rep,
(struct reply_info*)e->data,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
- &edns)) {
@@ -244,7 +244,7 @@ index 23e3244c..b63d49b7 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
@@ -1548,11 +1605,19 @@ lookup_cache:
@@ -1514,11 +1571,19 @@
lock_rw_unlock(&e->lock);
}
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
@@ -266,11 +266,11 @@ index 23e3244c..b63d49b7 100644
goto send_reply;
}
verbose(VERB_ALGO, "answer norec from cache -- "
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index cd43f04e..b92a1af8 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -1878,6 +1878,81 @@ List domain for which the AAAA records are ignored and the A record is
Index: unboundfastrpz/doc/unbound.conf.5.in
===================================================================
--- unboundfastrpz/doc/unbound.conf.5.in (revision 5073)
+++ unboundfastrpz/doc/unbound.conf.5.in (working copy)
@@ -1781,6 +1781,81 @@
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.
@@ -352,11 +352,10 @@ index cd43f04e..b92a1af8 100644
.SS "DNSCrypt Options"
.LP
The
diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
new file mode 100644
index 00000000..645279d1
--- /dev/null
+++ b/fastrpz/librpz.h
Index: unboundfastrpz/fastrpz/librpz.h
===================================================================
--- unboundfastrpz/fastrpz/librpz.h (nonexistent)
+++ unboundfastrpz/fastrpz/librpz.h (working copy)
@@ -0,0 +1,957 @@
+/*
+ * Define the interface from a DNS resolver to the Response Policy Zone
@@ -1315,11 +1314,10 @@ index 00000000..645279d1
+#endif /* LIBRPZ_LIB_OPEN */
+
+#endif /* LIBRPZ_H */
diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
new file mode 100644
index 00000000..c5ab7801
--- /dev/null
+++ b/fastrpz/rpz.c
Index: unboundfastrpz/fastrpz/rpz.c
===================================================================
--- unboundfastrpz/fastrpz/rpz.c (nonexistent)
+++ unboundfastrpz/fastrpz/rpz.c (working copy)
@@ -0,0 +1,1352 @@
+/*
+ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
@@ -2673,11 +2671,10 @@ index 00000000..c5ab7801
+}
+
+#endif /* ENABLE_FASTRPZ */
diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
new file mode 100644
index 00000000..5d7e31c5
--- /dev/null
+++ b/fastrpz/rpz.h
Index: unboundfastrpz/fastrpz/rpz.h
===================================================================
--- unboundfastrpz/fastrpz/rpz.h (nonexistent)
+++ unboundfastrpz/fastrpz/rpz.h (working copy)
@@ -0,0 +1,138 @@
+/*
+ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
@@ -2817,11 +2814,10 @@ index 00000000..5d7e31c5
+
+#endif /* ENABLE_FASTRPZ */
+#endif /* UNBOUND_FASTRPZ_RPZ_H */
diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
new file mode 100644
index 00000000..21235355
--- /dev/null
+++ b/fastrpz/rpz.m4
Index: unboundfastrpz/fastrpz/rpz.m4
===================================================================
--- unboundfastrpz/fastrpz/rpz.m4 (nonexistent)
+++ unboundfastrpz/fastrpz/rpz.m4 (working copy)
@@ -0,0 +1,64 @@
+# fastrpz/rpz.m4
+
@@ -2887,10 +2883,10 @@ index 00000000..21235355
+ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
+ fi
+])
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 23b07ea9..c3d31a33 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
Index: unboundfastrpz/iterator/iterator.c
===================================================================
--- unboundfastrpz/iterator/iterator.c (revision 5073)
+++ unboundfastrpz/iterator/iterator.c (working copy)
@@ -68,6 +68,9 @@
#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
@@ -2901,7 +2897,7 @@ index 23b07ea9..c3d31a33 100644
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
@@ -563,6 +566,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -551,6 +554,23 @@
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 +2921,7 @@ index 23b07ea9..c3d31a33 100644
/* Add this relevant CNAME rrset to the prepend list.*/
if(!iter_add_prepend_answer(qstate, iq, r))
return 0;
@@ -571,6 +591,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -559,6 +579,9 @@
/* Other rrsets in the section are ignored. */
}
@@ -2935,7 +2931,7 @@ index 23b07ea9..c3d31a33 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++) {
@@ -1231,6 +1254,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1195,6 +1218,7 @@
uint8_t* delname;
size_t delnamelen;
struct dns_msg* msg = NULL;
@@ -2943,7 +2939,7 @@ index 23b07ea9..c3d31a33 100644
log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
/* check effort */
@@ -1317,8 +1341,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1281,8 +1305,7 @@
}
if(msg) {
/* handle positive cache response */
@@ -2953,7 +2949,7 @@ index 23b07ea9..c3d31a33 100644
if(verbosity >= VERB_ALGO) {
log_dns_msg("msg from cache lookup", &msg->qinfo,
msg->rep);
@@ -1326,7 +1349,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -1290,7 +1313,22 @@
(int)msg->rep->ttl,
(int)msg->rep->prefetch_ttl);
}
@@ -2976,7 +2972,7 @@ index 23b07ea9..c3d31a33 100644
if(type == RESPONSE_TYPE_CNAME) {
uint8_t* sname = 0;
size_t slen = 0;
@@ -2801,6 +2839,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -2694,6 +2732,62 @@
sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
@@ -3039,7 +3035,7 @@ index 23b07ea9..c3d31a33 100644
if(iq->minimisation_state != DONOT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
@@ -3563,12 +3657,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -3440,6 +3534,10 @@
* 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) {
@@ -3050,6 +3046,7 @@ index 23b07ea9..c3d31a33 100644
iter_dns_store(qstate->env, &qstate->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
@@ -3446,6 +3544,34 @@
qstate->region, qstate->query_flags);
}
}
@@ -3084,11 +3081,11 @@ index 23b07ea9..c3d31a33 100644
qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = iq->response;
return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h
index 342ac207..49b0ecdd 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -396,6 +396,16 @@ struct iter_qstate {
Index: unboundfastrpz/iterator/iterator.h
===================================================================
--- unboundfastrpz/iterator/iterator.h (revision 5073)
+++ unboundfastrpz/iterator/iterator.h (working copy)
@@ -386,6 +386,16 @@
*/
int minimise_count;
@@ -3104,12 +3101,12 @@ index 342ac207..49b0ecdd 100644
+
/**
* Count number of time-outs. Used to prevent resolving failures when
* the QNAME minimisation QTYPE is blocked. Used to determine if
diff --git a/services/cache/dns.c b/services/cache/dns.c
index 7b6e142c..6d7449f5 100644
--- a/services/cache/dns.c
+++ b/services/cache/dns.c
@@ -969,6 +969,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
* the QNAME minimisation QTYPE is blocked. */
Index: unboundfastrpz/services/cache/dns.c
===================================================================
--- unboundfastrpz/services/cache/dns.c (revision 5073)
+++ unboundfastrpz/services/cache/dns.c (working copy)
@@ -939,6 +939,14 @@
struct regional* region, uint32_t flags)
{
struct reply_info* rep = NULL;
@@ -3124,11 +3121,11 @@ index 7b6e142c..6d7449f5 100644
/* alloc, malloc properly (not in region, like msg is) */
rep = reply_info_copy(msgrep, env->alloc, NULL);
if(!rep)
diff --git a/services/mesh.c b/services/mesh.c
index 4b0c5db4..eb9cfa5b 100644
--- a/services/mesh.c
+++ b/services/mesh.c
@@ -61,6 +61,9 @@
Index: unboundfastrpz/services/mesh.c
===================================================================
--- unboundfastrpz/services/mesh.c (revision 5073)
+++ unboundfastrpz/services/mesh.c (working copy)
@@ -60,6 +60,9 @@
#include "sldns/wire2str.h"
#include "services/localzone.h"
#include "util/data/dname.h"
@@ -3138,7 +3135,7 @@ index 4b0c5db4..eb9cfa5b 100644
#include "respip/respip.h"
#include "services/listen_dnsport.h"
@@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
@@ -1072,6 +1075,13 @@
else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL;
@@ -3152,7 +3149,7 @@ index 4b0c5db4..eb9cfa5b 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
@@ -1434,6 +1444,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
@@ -1247,6 +1257,7 @@
key.s.is_valrec = valrec;
key.s.qinfo = *qinfo;
key.s.query_flags = qflags;
@@ -3160,7 +3157,7 @@ index 4b0c5db4..eb9cfa5b 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).*/
@@ -1480,6 +1491,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
@@ -1293,6 +1304,10 @@
if(!r)
return 0;
r->query_reply = *rep;
@@ -3171,24 +3168,24 @@ index 4b0c5db4..eb9cfa5b 100644
r->edns = *edns;
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 0e9ee471..a5fd72e0 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -1495,6 +1495,8 @@ config_delete(struct config_file* cfg)
free(cfg->dnstap_tls_client_cert_file);
Index: unboundfastrpz/util/config_file.c
===================================================================
--- unboundfastrpz/util/config_file.c (revision 5073)
+++ unboundfastrpz/util/config_file.c (working copy)
@@ -1418,6 +1418,8 @@
free(cfg->dnstap_socket_path);
free(cfg->dnstap_identity);
free(cfg->dnstap_version);
+ if (cfg->rpz_cstr)
+ free(cfg->rpz_cstr);
config_deldblstrlist(cfg->ratelimit_for_domain);
config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script);
diff --git a/util/config_file.h b/util/config_file.h
index 66e5025d..504f4f92 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -522,6 +522,11 @@ struct config_file {
#ifdef USE_IPSECMOD
Index: unboundfastrpz/util/config_file.h
===================================================================
--- unboundfastrpz/util/config_file.h (revision 5073)
+++ unboundfastrpz/util/config_file.h (working copy)
@@ -490,6 +490,11 @@
/** true to disable DNSSEC lameness check in iterator */
int disable_dnssec_lame_check;
@@ -3200,11 +3197,11 @@ index 66e5025d..504f4f92 100644
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
int ip_ratelimit;
/** number of slabs for ip_ratelimit cache */
diff --git a/util/configlexer.lex b/util/configlexer.lex
index 83cea4b9..9a7feea4 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -467,6 +467,10 @@ dnstap-log-forwarder-query-messages{COLON} {
Index: unboundfastrpz/util/configlexer.lex
===================================================================
--- unboundfastrpz/util/configlexer.lex (revision 5073)
+++ unboundfastrpz/util/configlexer.lex (working copy)
@@ -439,6 +439,10 @@
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
dnstap-log-forwarder-response-messages{COLON} {
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
@@ -3215,19 +3212,19 @@ index 83cea4b9..9a7feea4 100644
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
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 fe600a99..ce43390f 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -128,6 +128,7 @@ extern struct config_parser_state* cfg_parser;
Index: unboundfastrpz/util/configparser.y
===================================================================
--- unboundfastrpz/util/configparser.y (revision 5073)
+++ unboundfastrpz/util/configparser.y (working copy)
@@ -125,6 +125,7 @@
%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_IP_DSCP
@@ -179,7 +180,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DISABLE_DNSSEC_LAME_CHECK
@@ -170,7 +171,7 @@
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -3236,7 +3233,7 @@ index fe600a99..ce43390f 100644
forwardstart contents_forward | pythonstart contents_py |
rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
dnscstart contents_dnsc | cachedbstart contents_cachedb |
@@ -2939,6 +2940,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
@@ -2708,6 +2709,50 @@
free($2);
}
;
@@ -3264,8 +3261,8 @@ index fe600a99..ce43390f 100644
+
+ OUTYY(("P(rpz_zone:%s)\n", $2));
+ old_cstr = cfg_parser->cfg->rpz_cstr;
+ if(asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
+ else if(!new_cstr)
+ (void)asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2);
+ if(!new_cstr)
+ yyerror("out of memory");
+ free(old_cstr);
+ cfg_parser->cfg->rpz_cstr = new_cstr;
@@ -3277,8 +3274,8 @@ index fe600a99..ce43390f 100644
+
+ OUTYY(("P(rpz_option:%s)\n", $2));
+ old_cstr = cfg_parser->cfg->rpz_cstr;
+ if(asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
+ else if(!new_cstr)
+ (void)asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2);
+ if(!new_cstr)
+ yyerror("out of memory");
+ free(old_cstr);
+ cfg_parser->cfg->rpz_cstr = new_cstr;
@@ -3287,11 +3284,11 @@ index fe600a99..ce43390f 100644
pythonstart: VAR_PYTHON
{
OUTYY(("\nP(python:)\n"));
diff --git a/util/data/msgencode.c b/util/data/msgencode.c
index be69f628..f10773aa 100644
--- a/util/data/msgencode.c
+++ b/util/data/msgencode.c
@@ -592,6 +592,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
Index: unboundfastrpz/util/data/msgencode.c
===================================================================
--- unboundfastrpz/util/data/msgencode.c (revision 5073)
+++ unboundfastrpz/util/data/msgencode.c (working copy)
@@ -590,6 +590,35 @@
return RETVAL_OK;
}
@@ -3327,10 +3324,10 @@ index be69f628..f10773aa 100644
/** store query section in wireformat buffer, return RETVAL */
static int
insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
@@ -779,6 +808,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
}
sldns_buffer_write_u16_at(buffer, 10, arcount);
@@ -753,6 +782,19 @@
return 0;
}
sldns_buffer_write_u16_at(buffer, 10, arcount);
+#ifdef ENABLE_FASTRPZ
+ } else if(rep->security == sec_status_rpz_rewritten) {
+ /* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */
@@ -3347,11 +3344,11 @@ index be69f628..f10773aa 100644
}
sldns_buffer_flip(buffer);
return 1;
diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
index 4b0294f9..3b3838f6 100644
--- a/util/data/packed_rrset.c
+++ b/util/data/packed_rrset.c
@@ -256,6 +256,10 @@ sec_status_to_string(enum sec_status s)
Index: unboundfastrpz/util/data/packed_rrset.c
===================================================================
--- unboundfastrpz/util/data/packed_rrset.c (revision 5073)
+++ unboundfastrpz/util/data/packed_rrset.c (working copy)
@@ -255,6 +255,10 @@
case sec_status_insecure: return "sec_status_insecure";
case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
case sec_status_secure: return "sec_status_secure";
@@ -3362,11 +3359,11 @@ index 4b0294f9..3b3838f6 100644
}
return "unknown_sec_status_value";
}
diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
index 729877ba..ccd1a0c2 100644
--- a/util/data/packed_rrset.h
+++ b/util/data/packed_rrset.h
@@ -193,7 +193,15 @@ enum sec_status {
Index: unboundfastrpz/util/data/packed_rrset.h
===================================================================
--- unboundfastrpz/util/data/packed_rrset.h (revision 5073)
+++ unboundfastrpz/util/data/packed_rrset.h (working copy)
@@ -193,7 +193,15 @@
sec_status_secure_sentinel_fail,
/** SECURE means that the object (RRset or message) validated
* according to local policy. */
@@ -3383,10 +3380,10 @@ index 729877ba..ccd1a0c2 100644
};
/**
diff --git a/util/netevent.c b/util/netevent.c
index 3e7a433e..f20d806f 100644
--- a/util/netevent.c
+++ b/util/netevent.c
Index: unboundfastrpz/util/netevent.c
===================================================================
--- unboundfastrpz/util/netevent.c (revision 5073)
+++ unboundfastrpz/util/netevent.c (working copy)
@@ -57,6 +57,9 @@
#ifdef HAVE_OPENSSL_ERR_H
#include <openssl/err.h>
@@ -3397,7 +3394,7 @@ index 3e7a433e..f20d806f 100644
/* -------- Start of local definitions -------- */
/** if CMSG_ALIGN is not defined on this platform, a workaround */
@@ -596,6 +599,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
@@ -590,6 +593,9 @@
struct cmsghdr* cmsg;
#endif /* S_SPLINT_S */
@@ -3407,7 +3404,7 @@ index 3e7a433e..f20d806f 100644
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -685,6 +691,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
@@ -679,6 +685,9 @@
int i;
struct sldns_buffer *buffer;
@@ -3417,7 +3414,7 @@ index 3e7a433e..f20d806f 100644
rep.c = (struct comm_point*)arg;
log_assert(rep.c->type == comm_udp);
@@ -728,6 +737,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
@@ -722,6 +731,9 @@
(void)comm_point_send_udp_msg(rep.c, buffer,
(struct sockaddr*)&rep.addr, rep.addrlen);
}
@@ -3427,7 +3424,7 @@ index 3e7a433e..f20d806f 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;
@@ -3175,6 +3187,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
@@ -3108,6 +3120,9 @@
repinfo->c->tcp_timeout_msec);
}
}
@@ -3437,9 +3434,9 @@ index 3e7a433e..f20d806f 100644
}
void
@@ -3184,6 +3199,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
@@ -3117,6 +3132,9 @@
return;
log_assert(repinfo->c);
log_assert(repinfo && repinfo->c);
log_assert(repinfo->c->type != comm_tcp_accept);
+#ifdef ENABLE_FASTRPZ
+ rpz_end(repinfo);
@@ -3447,21 +3444,21 @@ index 3e7a433e..f20d806f 100644
if(repinfo->c->type == comm_udp)
return;
if(repinfo->c->tcp_req_info)
@@ -3205,6 +3223,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
@@ -3138,6 +3156,9 @@
{
verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
c->fd==-1?newfd:c->fd, msec);
verbose(VERB_ALGO, "comm point start listening %d",
c->fd==-1?newfd:c->fd);
+#ifdef ENABLE_FASTRPZ
+ rpz_end(&c->repinfo);
+#endif
if(c->type == comm_tcp_accept && !c->tcp_free) {
/* no use to start listening no free slots. */
return;
diff --git a/util/netevent.h b/util/netevent.h
index bb2cd1e5..666067e8 100644
--- a/util/netevent.h
+++ b/util/netevent.h
@@ -120,6 +120,10 @@ struct comm_reply {
Index: unboundfastrpz/util/netevent.h
===================================================================
--- unboundfastrpz/util/netevent.h (revision 5073)
+++ unboundfastrpz/util/netevent.h (working copy)
@@ -120,6 +120,10 @@
/** return type 0 (none), 4(IP4), 6(IP6) */
int srctype;
/* DnsCrypt context */
@@ -3472,11 +3469,11 @@ index bb2cd1e5..666067e8 100644
#ifdef USE_DNSCRYPT
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
uint8_t nmkey[crypto_box_BEFORENMBYTES];
diff --git a/validator/validator.c b/validator/validator.c
index c3ca0a27..15251988 100644
--- a/validator/validator.c
+++ b/validator/validator.c
@@ -2761,6 +2761,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
Index: unboundfastrpz/validator/validator.c
===================================================================
--- unboundfastrpz/validator/validator.c (revision 5073)
+++ unboundfastrpz/validator/validator.c (working copy)
@@ -2755,6 +2755,12 @@
default:
/* NSEC proof did not work, try next */
break;
@@ -3489,7 +3486,7 @@ index c3ca0a27..15251988 100644
}
sec = nsec3_prove_nods(qstate->env, ve,
@@ -2794,6 +2800,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
@@ -2788,6 +2794,12 @@
default:
/* NSEC3 proof did not work */
break;
-325
View File
@@ -1,325 +0,0 @@
diff --git a/sldns/keyraw.c b/sldns/keyraw.c
index 42a9262a3..cc6406a56 100644
--- a/sldns/keyraw.c
+++ b/sldns/keyraw.c
@@ -85,7 +85,7 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
}
break;
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
return 512;
#endif
#ifdef USE_ECDSA
@@ -146,7 +146,7 @@ sldns_key_EVP_load_gost_id(void)
if(gost_id) return gost_id;
/* see if configuration loaded gost implementation from other engine*/
- meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
+ meth = EVP_PKEY_asn1_find_str(NULL, "gost2012_256", -1);
if(meth) {
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
return gost_id;
@@ -170,7 +170,7 @@ sldns_key_EVP_load_gost_id(void)
return 0;
}
- meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
+ meth = EVP_PKEY_asn1_find_str(&e, "gost2012_256", -1);
if(!meth) {
/* algo not found */
ENGINE_finish(e);
@@ -536,12 +536,17 @@ EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
EVP_PKEY*
sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
{
- /* prefix header for X509 encoding */
- uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
- 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
- 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
- unsigned char encoded[37+64];
+ /* prefix header for X509 encoding
+ *
+ * note: based on draft-makarenko-gost2012-dnssec-01 (pre-RFC9558 and it DOES work!)
+ * ASN1 header described in RFC9558 is not suitable due to d2i_PUBKEY() works with
+ * non-compressed public keys (two additional bytes 0x04, 0x40 at the end of header)
+ */
+ uint8_t asn[32] = { 0x30, 0x5e, 0x30, 0x17, 0x06, 0x08, 0x2a, 0x85,
+ 0x03, 0x07, 0x01, 0x01, 0x01, 0x01, 0x30, 0x0b,
+ 0x06, 0x09, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x02,
+ 0x01, 0x01, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40 };
+ unsigned char encoded[32+64];
const unsigned char* pp;
if(keylen != 64) {
/* key wrong size */
@@ -549,8 +554,8 @@ sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
}
/* create evp_key */
- memmove(encoded, asn, 37);
- memmove(encoded+37, key, 64);
+ memmove(encoded, asn, 32);
+ memmove(encoded+32, key, 64);
pp = (unsigned char*)&encoded[0];
return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
diff --git a/sldns/rrdef.h b/sldns/rrdef.h
index bbc3d5b86..7d5f3c057 100644
--- a/sldns/rrdef.h
+++ b/sldns/rrdef.h
@@ -384,11 +384,12 @@ enum sldns_enum_algorithm
LDNS_RSASHA1_NSEC3 = 7,
LDNS_RSASHA256 = 8, /* RFC 5702 */
LDNS_RSASHA512 = 10, /* RFC 5702 */
- LDNS_ECC_GOST = 12, /* RFC 5933 */
+ LDNS_ECC_GOST = 12, /* RFC 5933, deprecated */
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
LDNS_ED25519 = 15, /* RFC 8080 */
LDNS_ED448 = 16, /* RFC 8080 */
+ LDNS_ECC_GOST12 = 23, /* RFC 9558 */
LDNS_INDIRECT = 252,
LDNS_PRIVATEDNS = 253,
LDNS_PRIVATEOID = 254
@@ -402,8 +403,9 @@ enum sldns_enum_hash
{
LDNS_SHA1 = 1, /* RFC 4034 */
LDNS_SHA256 = 2, /* RFC 4509 */
- LDNS_HASH_GOST = 3, /* RFC 5933 */
- LDNS_SHA384 = 4 /* RFC 6605 */
+ LDNS_HASH_GOST = 3, /* RFC 5933, deprecated */
+ LDNS_SHA384 = 4, /* RFC 6605 */
+ LDNS_HASH_GOST12 = 5 /* RFC 9558 */
};
typedef enum sldns_enum_hash sldns_hash;
diff --git a/sldns/wire2str.c b/sldns/wire2str.c
index 75b8f37b0..b4c4755e6 100644
--- a/sldns/wire2str.c
+++ b/sldns/wire2str.c
@@ -45,11 +45,12 @@ static sldns_lookup_table sldns_algorithms_data[] = {
{ LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
{ LDNS_RSASHA256, "RSASHA256"},
{ LDNS_RSASHA512, "RSASHA512"},
- { LDNS_ECC_GOST, "ECC-GOST"},
+ { LDNS_ECC_GOST, "ECC-GOST"}, /* deprecated */
{ LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
{ LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
{ LDNS_ED25519, "ED25519"},
{ LDNS_ED448, "ED448"},
+ { LDNS_ECC_GOST12, "ECC-GOST12"},
{ LDNS_INDIRECT, "INDIRECT" },
{ LDNS_PRIVATEDNS, "PRIVATEDNS" },
{ LDNS_PRIVATEOID, "PRIVATEOID" },
@@ -61,8 +62,9 @@ sldns_lookup_table* sldns_algorithms = sldns_algorithms_data;
static sldns_lookup_table sldns_hashes_data[] = {
{ LDNS_SHA1, "SHA1" },
{ LDNS_SHA256, "SHA256" },
- { LDNS_HASH_GOST, "HASH-GOST" },
+ { LDNS_HASH_GOST, "HASH-GOST" }, /* deprecated */
{ LDNS_SHA384, "SHA384" },
+ { LDNS_HASH_GOST12, "HASH-GOST12" },
{ 0, NULL }
};
sldns_lookup_table* sldns_hashes = sldns_hashes_data;
diff --git a/testcode/unitverify.c b/testcode/unitverify.c
index fcf2e2ffe..4a33e9f6a 100644
--- a/testcode/unitverify.c
+++ b/testcode/unitverify.c
@@ -696,7 +696,7 @@ verify_test(void)
#endif
#ifdef USE_GOST
if(sldns_key_EVP_load_gost_id())
- verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504");
+ verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost12", "20251226060504");
else printf("Warning: skipped GOST, openssl does not provide gost.\n");
#endif
#ifdef USE_ECDSA
diff --git a/testdata/test_sigs.gost12 b/testdata/test_sigs.gost12
new file mode 100644
index 000000000..72a250cff
--- /dev/null
+++ b/testdata/test_sigs.gost12
@@ -0,0 +1,39 @@
+; Signature test file
+
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification.
+; later entries are verified with it.
+
+; Test GOST signatures using algo number 23.
+
+ENTRY_BEGIN
+SECTION QUESTION
+nlnetlabs.nl. IN DNSKEY
+SECTION ANSWER
+nlnetlabs.nl. 3600 IN DNSKEY 256 3 23 cdOtkEcb6NhcdOpIbPYtWyWxdlUiKgtKQbYg3lIjtG7i3fYjUID9zyOgoQEiV9wuGCfrw5cNsnvNw+8HiVFK4g== ;{id = 12301 (zsk), size = 512b}
+ENTRY_END
+
+; entry to test
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN A
+SECTION ANSWER
+open.nlnetlabs.nl. 600 IN A 213.154.224.1
+open.nlnetlabs.nl. 600 IN RRSIG A 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. I12wYNs96DxMy26CWx296/sWMJAFg4nNXBo0sw7PnuMbJW5NFAmZYtFWhUdOWn4umaiodYOAmKG8Zg/OKvEtAQ==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN AAAA
+SECTION ANSWER
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::1
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::53
+open.nlnetlabs.nl. 600 IN RRSIG AAAA 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. J0jHa+CP8HM6UDa2+uYgaze2mfpJTh2hkZ2KwMTYb5sfL6iBmxxql0c/403Itk4fMfYBMGn7zfzDQ+CxnCgSWw==
+ENTRY_END
+
+ENTRY_BEGIN
+SECTION QUESTION
+open.nlnetlabs.nl. IN NSEC
+SECTION ANSWER
+open.nlnetlabs.nl. 86400 IN NSEC nlnetlabs.nl. A AAAA RRSIG NSEC
+open.nlnetlabs.nl. 86400 IN RRSIG NSEC 23 3 86400 20260122084903 20251225084903 12301 nlnetlabs.nl. INCLYe9vAaNYaYx5Ay3Q6QdX+wPW9sMRvVlGt/jUEGgCi+88QlV80CT1oHrhRI66I14Wk6NRAGZRNx1tUPSHSg==
+ENTRY_END
diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c
index be8347b1b..4f621a309 100644
--- a/validator/val_secalgo.c
+++ b/validator/val_secalgo.c
@@ -246,10 +246,10 @@ ds_digest_size_supported(int algo)
return SHA256_DIGEST_LENGTH;
#endif
#ifdef USE_GOST
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
/* we support GOST if it can be loaded */
(void)sldns_key_EVP_load_gost_id();
- if(EVP_get_digestbyname("md_gost94"))
+ if(EVP_get_digestbyname("md_gost12_256"))
return 32;
else return 0;
#endif
@@ -265,9 +265,9 @@ ds_digest_size_supported(int algo)
#ifdef USE_GOST
/** Perform GOST hash */
static int
-do_gost94(unsigned char* data, size_t len, unsigned char* dest)
+do_gost12(unsigned char* data, size_t len, unsigned char* dest)
{
- const EVP_MD* md = EVP_get_digestbyname("md_gost94");
+ const EVP_MD* md = EVP_get_digestbyname("md_gost12_256");
if(!md)
return 0;
return sldns_digest_evp(data, (unsigned int)len, dest, md);
@@ -302,8 +302,8 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return 1;
#endif
#ifdef USE_GOST
- case LDNS_HASH_GOST:
- if(do_gost94(buf, len, res))
+ case LDNS_HASH_GOST12:
+ if(do_gost12(buf, len, res))
return 1;
break;
#endif
@@ -384,7 +384,7 @@ dnskey_algo_id_is_supported(int id)
#endif
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
/* we support GOST if it can be loaded */
return sldns_key_EVP_load_gost_id();
#endif
@@ -612,17 +612,17 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
break;
#ifdef USE_GOST
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
*evp_key = sldns_gost2pkey_raw(key, keylen);
if(!*evp_key) {
verbose(VERB_QUERY, "verify: "
"sldns_gost2pkey_raw failed");
return 0;
}
- *digest_type = EVP_get_digestbyname("md_gost94");
+ *digest_type = EVP_get_digestbyname("md_gost12_256");
if(!*digest_type) {
verbose(VERB_QUERY, "verify: "
- "EVP_getdigest md_gost94 failed");
+ "EVP_getdigest md_gost12_256 failed");
return 0;
}
break;
@@ -964,7 +964,7 @@ ds_digest_size_supported(int algo)
return SHA384_LENGTH;
#endif
/* GOST not supported in NSS */
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
default: break;
}
return 0;
@@ -991,7 +991,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
== SECSuccess;
#endif
- case LDNS_HASH_GOST:
+ case LDNS_HASH_GOST12:
default:
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
algo);
@@ -1031,7 +1031,7 @@ dnskey_algo_id_is_supported(int id)
case LDNS_ECDSAP384SHA384:
return PK11_TokenExists(CKM_ECDSA);
#endif
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
return 0;
}
@@ -1352,7 +1352,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
/* no prefix for DSA verification */
break;
#endif /* USE_ECDSA */
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
verbose(VERB_QUERY, "verify: unknown algorithm %d",
algo);
@@ -1675,7 +1675,7 @@ ds_digest_size_supported(int algo)
return SHA384_DIGEST_SIZE;
#endif
/* GOST not supported */
- case LDNS_HASH_GOST:
+ case LDNS_ECC_GOST12:
default:
break;
}
@@ -1700,7 +1700,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res);
#endif
- case LDNS_HASH_GOST:
+ case LDNS_ECC_GOST12:
default:
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
algo);
@@ -1744,7 +1744,7 @@ dnskey_algo_id_is_supported(int id)
return 1;
#endif
case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
return 0;
}
@@ -2103,7 +2103,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
return sec_status_secure;
#endif
case LDNS_RSAMD5:
- case LDNS_ECC_GOST:
+ case LDNS_ECC_GOST12:
default:
*reason = "unable to verify signature, unknown algorithm";
return sec_status_bogus;
-41
View File
@@ -1,41 +0,0 @@
#### 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"),
},
);
-60
View File
@@ -1,60 +0,0 @@
#!/usr/bin/env bash
LIBEXPAT_FNAME=expat-2.7.0
LIBEXPAT_VERSION_DIR=R_2_7_0
echo "Downloading Expat"
if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz;
then
echo "Failed to download Expat"
exit 1
fi
echo "Unpacking Expat"
rm -rf ./$LIBEXPAT_FNAME
if ! tar -xf $LIBEXPAT_FNAME.tar.gz;
then
echo "Failed to unpack Expat"
exit 1
fi
cd $LIBEXPAT_FNAME || exit 1
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
echo "Configuring Expat"
if ! ./configure --without-tests \
--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
-54
View File
@@ -1,54 +0,0 @@
#!/usr/bin/env bash
OPENSSL_VERSION=1.1.1d
echo "Downloading OpenSSL"
if ! curl -L -k -s -o openssl-$OPENSSL_VERSION.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz;
then
echo "Failed to download OpenSSL"
exit 1
fi
echo "Unpacking OpenSSL"
rm -rf ./openssl-$OPENSSL_VERSION
if ! tar -xf openssl-$OPENSSL_VERSION.tar.gz;
then
echo "Failed to unpack OpenSSL"
exit 1
fi
cd openssl-$OPENSSL_VERSION || 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"
# the partial patch may be useful.
#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
-10
View File
@@ -1,10 +0,0 @@
#!/usr/bin/env bash
# This step should install tools needed for all packages - OpenSSL, Expat and Unbound
# brew update hangs, so we try to skip that step.
#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
HOMEBREW_NO_AUTO_UPDATE=1 brew install curl perl 1>/dev/null
-48
View File
@@ -1,48 +0,0 @@
--- 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
-279
View File
@@ -1,279 +0,0 @@
#!/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=
if test -z "$SDK_VERSION"; then
for i in $(seq -f "%.1f" 30.0 -0.1 1.0)
do
if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then
XCODE_SDK="$IOS_SDK$i.sdk"
break
fi
done
else
i="$SDK_VERSION"
XCODE_SDK="$IOS_SDK$i.sdk"
fi
# 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
+4 -3
View File
@@ -7,7 +7,8 @@ Name: unbound
Description: Library with validating, recursive, and caching DNS resolver
URL: http://www.unbound.net
Version: @PACKAGE_VERSION@
Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@ @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
Libs: -L${libdir} -lunbound
Requires: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@
Requires.private: @PC_PY_DEPENDENCY@
Libs: -L${libdir} -lunbound -lssl -lcrypto
Libs.private: @SSLLIB@ @LIBS@
Cflags: -I${includedir}
Cflags: -I${includedir}
-1
View File
@@ -14,7 +14,6 @@ int ub_ctx_set_option(ub_ctx*, string, string);
int ub_ctx_get_option(ub_ctx*, string, +string*);
int ub_ctx_config(ub_ctx*, string);
int ub_ctx_set_fwd(ub_ctx*, string);
int ub_ctx_set_tls(ub_ctx*, bool(int));
int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
int ub_ctx_resolvconf(ub_ctx*, string);
int ub_ctx_hosts(ub_ctx*, string);
-181
View File
@@ -1,181 +0,0 @@
# read output of unbound-control stats
# and output prometheus metrics style output.
# use these options:
# server: extended-statistics: yes
# statistics-cumulative: no
# statistics-interval: 0
# remote-control: control-enable: yes
# Can use it like unbound-control stats | awk -f "metrics.awk"
BEGIN {
FS="=";
}
# everything like total.num.queries=value is put in val["total.num.queries"]
/^.*\..*=/ {
val[$1]=$2;
}
# print the output metrics
END {
print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
print "# TYPE unbound_hits_queries gauge"
print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
for (x=0; x<99; x++) {
if(val["thread" $x ".num.queries"] != "") {
print "unbound_hits_queries{type=\"thread" $x ".num.queries\"} " val["thread" $x ".num.queries"];
}
}
print "unbound_hits_queries{type=\"total.num.cachehits\"} " val["total.num.cachehits"];
print "unbound_hits_queries{type=\"total.num.prefetch\"} " val["total.num.prefetch"];
print "unbound_hits_queries{type=\"num.query.tcp\"} " val["num.query.tcp"];
print "unbound_hits_queries{type=\"num.query.tcpout\"} " val["num.query.tcpout"];
print "unbound_hits_queries{type=\"num.query.udpout\"} " val["num.query.udpout"];
print "unbound_hits_queries{type=\"num.query.tls\"} " val["num.query.tls"];
print "unbound_hits_queries{type=\"num.query.tls.resume\"} " val["num.query.tls.resume"];
print "unbound_hits_queries{type=\"num.query.ipv6\"} " val["num.query.ipv6"];
print "unbound_hits_queries{type=\"unwanted.queries\"} " val["unwanted.queries"];
print ""
print "# HELP unbound_queue_queries Unbound requestlist size"
print "# TYPE unbound_queue_queries gauge"
print "unbound_queue_queries{type=\"total.requestlist.avg\"} " val["total.requestlist.avg"];
print "unbound_queue_queries{type=\"total.requestlist.max\"} " val["total.requestlist.max"];
print "unbound_queue_queries{type=\"total.requestlist.overwritten\"} " val["total.requestlist.overwritten"];
print "unbound_queue_queries{type=\"total.requestlist.exceeded\"} " val["total.requestlist.exceeded"];
print ""
print "# HELP unbound_memory_bytes Unbound memory usage"
print "# TYPE unbound_memory_bytes gauge"
print "unbound_memory_bytes{type=\"mem.cache.rrset\"} " val["mem.cache.rrset"];
print "unbound_memory_bytes{type=\"mem.cache.message\"} " val["mem.cache.message"];
print "unbound_memory_bytes{type=\"mem.mod.iterator\"} " val["mem.mod.iterator"];
if(val["mem.mod.validator"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.validator\"} " val["mem.mod.validator"];
}
if(val["mem.mod.respip"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.respip\"} " val["mem.mod.respip"];
}
if(val["mem.mod.subnet"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.subnet\"} " val["mem.mod.subnet"];
}
if(val["mem.mod.ipsecmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.ipsecmod\"} " val["mem.mod.ipsecmod"];
}
if(val["mem.mod.dynlibmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.dynlibmod\"} " val["mem.mod.dynlibmod"];
}
print "unbound_memory_bytes{type=\"msg.cache.count\"} " val["msg.cache.count"];
print "unbound_memory_bytes{type=\"rrset.cache.count\"} " val["rrset.cache.count"];
print "unbound_memory_bytes{type=\"infra.cache.count\"} " val["infra.cache.count"];
print "unbound_memory_bytes{type=\"key.cache.count\"} " val["key.cache.count"];
print ""
print "# HELP unbound_by_type_queries Unbound DNS queries by type"
print "# TYPE unbound_by_type_queries gauge"
for(x in val) {
if(x ~ /^num.query.type./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_type_queries{type=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_class_queries Unbound DNS queries by class"
print "# TYPE unbound_by_class_queries gauge"
for(x in val) {
if(x ~ /^num.query.class./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_class_queries{class=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
print "# TYPE unbound_by_opcode_queries gauge"
for(x in val) {
if(x ~ /^num.query.opcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_opcode_queries{opcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
print "# TYPE unbound_by_rcode_queries gauge"
for(x in val) {
if(x ~ /^num.answer.rcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_rcode_queries{rcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
print "# TYPE unbound_by_flags_queries gauge"
for(x in val) {
if(x ~ /^num.query.flags./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_flags_queries{flag=\"" a[4] "\"} " val[x];
}
}
}
if(val["num.query.edns.present"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.present\"} " val["num.query.edns.present"];
}
if(val["num.query.edns.DO"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.DO\"} " val["num.query.edns.DO"];
}
print ""
print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
print "# TYPE unbound_histogram_seconds gauge"
print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
print "unbound_histogram_seconds{bucket=\"000000.000004.to.000000.000008\"} " val["histogram.000000.000004.to.000000.000008"];
print "unbound_histogram_seconds{bucket=\"000000.000008.to.000000.000016\"} " val["histogram.000000.000008.to.000000.000016"];
print "unbound_histogram_seconds{bucket=\"000000.000016.to.000000.000032\"} " val["histogram.000000.000016.to.000000.000032"];
print "unbound_histogram_seconds{bucket=\"000000.000032.to.000000.000064\"} " val["histogram.000000.000032.to.000000.000064"];
print "unbound_histogram_seconds{bucket=\"000000.000064.to.000000.000128\"} " val["histogram.000000.000064.to.000000.000128"];
print "unbound_histogram_seconds{bucket=\"000000.000128.to.000000.000256\"} " val["histogram.000000.000128.to.000000.000256"];
print "unbound_histogram_seconds{bucket=\"000000.000256.to.000000.000512\"} " val["histogram.000000.000256.to.000000.000512"];
print "unbound_histogram_seconds{bucket=\"000000.000512.to.000000.001024\"} " val["histogram.000000.000512.to.000000.001024"];
print "unbound_histogram_seconds{bucket=\"000000.001024.to.000000.002048\"} " val["histogram.000000.001024.to.000000.002048"];
print "unbound_histogram_seconds{bucket=\"000000.002048.to.000000.004096\"} " val["histogram.000000.002048.to.000000.004096"];
print "unbound_histogram_seconds{bucket=\"000000.004096.to.000000.008192\"} " val["histogram.000000.004096.to.000000.008192"];
print "unbound_histogram_seconds{bucket=\"000000.008192.to.000000.016384\"} " val["histogram.000000.008192.to.000000.016384"];
print "unbound_histogram_seconds{bucket=\"000000.016384.to.000000.032768\"} " val["histogram.000000.016384.to.000000.032768"];
print "unbound_histogram_seconds{bucket=\"000000.032768.to.000000.065536\"} " val["histogram.000000.032768.to.000000.065536"];
print "unbound_histogram_seconds{bucket=\"000000.065536.to.000000.131072\"} " val["histogram.000000.065536.to.000000.131072"];
print "unbound_histogram_seconds{bucket=\"000000.131072.to.000000.262144\"} " val["histogram.000000.131072.to.000000.262144"];
print "unbound_histogram_seconds{bucket=\"000000.262144.to.000000.524288\"} " val["histogram.000000.262144.to.000000.524288"];
print "unbound_histogram_seconds{bucket=\"000000.524288.to.000001.000000\"} " val["histogram.000000.524288.to.000001.000000"];
print "unbound_histogram_seconds{bucket=\"000001.000000.to.000002.000000\"} " val["histogram.000001.000000.to.000002.000000"];
print "unbound_histogram_seconds{bucket=\"000002.000000.to.000004.000000\"} " val["histogram.000002.000000.to.000004.000000"];
print "unbound_histogram_seconds{bucket=\"000004.000000.to.000008.000000\"} " val["histogram.000004.000000.to.000008.000000"];
print "unbound_histogram_seconds{bucket=\"000008.000000.to.000016.000000\"} " val["histogram.000008.000000.to.000016.000000"];
print "unbound_histogram_seconds{bucket=\"000016.000000.to.000032.000000\"} " val["histogram.000016.000000.to.000032.000000"];
print "unbound_histogram_seconds{bucket=\"000032.000000.to.000064.000000\"} " val["histogram.000032.000000.to.000064.000000"];
print "unbound_histogram_seconds{bucket=\"000064.000000.to.000128.000000\"} " val["histogram.000064.000000.to.000128.000000"];
print "unbound_histogram_seconds{bucket=\"000128.000000.to.000256.000000\"} " val["histogram.000128.000000.to.000256.000000"];
print "unbound_histogram_seconds{bucket=\"000256.000000.to.000512.000000\"} " val["histogram.000256.000000.to.000512.000000"];
print "unbound_histogram_seconds{bucket=\"000512.000000.to.001024.000000\"} " val["histogram.000512.000000.to.001024.000000"];
print "unbound_histogram_seconds{bucket=\"001024.000000.to.002048.000000\"} " val["histogram.001024.000000.to.002048.000000"];
print "unbound_histogram_seconds{bucket=\"002048.000000.to.004096.000000\"} " val["histogram.002048.000000.to.004096.000000"];
print "unbound_histogram_seconds{bucket=\"004096.000000.to.008192.000000\"} " val["histogram.004096.000000.to.008192.000000"];
print "unbound_histogram_seconds{bucket=\"008192.000000.to.016384.000000\"} " val["histogram.008192.000000.to.016384.000000"];
print "unbound_histogram_seconds{bucket=\"016384.000000.to.032768.000000\"} " val["histogram.016384.000000.to.032768.000000"];
print "unbound_histogram_seconds{bucket=\"032768.000000.to.065536.000000\"} " val["histogram.032768.000000.to.065536.000000"];
print "unbound_histogram_seconds{bucket=\"065536.000000.to.131072.000000\"} " val["histogram.065536.000000.to.131072.000000"];
print "unbound_histogram_seconds{bucket=\"131072.000000.to.262144.000000\"} " val["histogram.131072.000000.to.262144.000000"];
print "unbound_histogram_seconds{bucket=\"262144.000000.to.524288.000000\"} " val["histogram.262144.000000.to.524288.000000"];
print ""
}
-9
View File
@@ -22,13 +22,4 @@ pidfile=${unbound_pidfile:-"/usr/local/etc/unbound/unbound.pid"}
command_args=${unbound_flags:-"-c /usr/local/etc/unbound/unbound.conf"}
extra_commands="reload"
if test "$1" = "stop" ; then
run_rc_command "$1"
ret=$?
if test $ret -eq 0; then
rm -f "$pidfile"
fi
exit $ret
fi
run_rc_command "$1"
Binary file not shown.
+7 -8
View File
@@ -39,13 +39,13 @@ start() {
# setup root jail
if [ -s /etc/localtime ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
cp -fp /etc/localtime ${rootdir}/etc/localtime
fi;
fi;
if [ -s /etc/resolv.conf ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
fi;
fi;
@@ -54,10 +54,10 @@ start() {
[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
fi;
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
[ -e ${rootdir}/dev/urandom ] || touch ${rootdir}/dev/urandom
mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
fi;
# if not running, start it up here
@@ -75,12 +75,11 @@ stop() {
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
umount ${rootdir}/dev/log >/dev/null 2>&1
fi;
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
umount ${rootdir}/dev/urandom >/dev/null 2>&1
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
umount ${rootdir}/dev/random >/dev/null 2>&1
fi;
return $retval
}
+2 -3
View File
@@ -42,7 +42,7 @@ start() {
cp -fp /etc/localtime ${rootdir}/etc/localtime
fi;
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
mount --bind -n /var/run/unbound ${rootdir}/var/run/unbound >/dev/null 2>&1;
# if not running, start it up here
@@ -58,8 +58,7 @@ stop() {
killproc -p $pidfile unbound
retval=$?
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound
for mountfile in /dev/log /dev/random /etc/localtime /etc/resolv.conf /var/run/unbound
do
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then
umount ${rootdir}$mountfile >/dev/null 2>&1
-140
View File
@@ -1,140 +0,0 @@
#!/bin/sh
#
# unbound This shell script takes care of starting and stopping
# unbound (DNS server).
#
# chkconfig: - 14 86
# description: unbound is a Domain Name Server (DNS) \
# that is used to resolve host names to IP addresses.
### BEGIN INIT INFO
# Provides: $named unbound
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Should-Start: $syslog
# Should-Stop: $syslog
# Short-Description: unbound recursive Domain Name Server.
# Description: unbound is a Domain Name Server (DNS)
# that is used to resolve host names to IP addresses.
### END INIT INFO
# Source function library.
. /etc/init.d/functions
exec="/usr/sbin/unbound"
prog="unbound"
config="/etc/unbound/unbound.conf"
pidfile="/var/unbound/unbound.pid"
rootdir="/var/unbound"
[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
lockfile=/var/lock/subsys/$prog
start() {
[ -x $exec ] || exit 5
[ -f $config ] || exit 6
echo -n $"Starting $prog: "
# setup root jail
if [ -s /etc/localtime ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
cp -fp /etc/localtime ${rootdir}/etc/localtime
fi;
fi;
if [ -s /etc/resolv.conf ]; then
[ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
fi;
fi;
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
[ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
fi;
if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
[ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
[ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
fi;
# if not running, start it up here
daemonize $exec
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc $prog"
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
[ $retval -eq 0 ] && rm -f $pidfile
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
umount ${rootdir}/dev/log >/dev/null 2>&1
fi;
if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
umount ${rootdir}/dev/random >/dev/null 2>&1
fi;
return $retval
}
restart() {
stop
start
}
reload() {
kill -HUP `cat $pidfile`
}
force_reload() {
restart
}
rh_status() {
# run checks to determine if the service is running or use generic status
status $prog
}
rh_status_q() {
rh_status -p $pidfile >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
restart
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
+9 -72
View File
@@ -1,94 +1,31 @@
; For further details about the directives used in this unit file, including
; the below, please refer to systemd's official documentation, available at
; https://www.freedesktop.org/software/systemd/man/systemd.exec.html.
;
;
; - `ProtectSystem=strict` implies we mount the entire file system hierarchy
; read-only for the processes invoked by the unit except for the API file
; system subtrees /dev, /proc and /sys (which are protected by
; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=).
;
; - `PrivateTmp=yes` secures access to temporary files of the process, and
; makes sharing between processes via /tmp or /var/tmp impossible.
;
; - `ProtectHome=yes` makes the directories /home, /root, and /run/user
; inaccessible and empty for processes invoked by the unit.
;
; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies
; (accessible through /sys/fs/cgroup) read-only to all processes invoked by
; the unit. It also implies `MountAPIVFS=yes`.
;
; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the
; unit User and Group with read-write permissions (0755) as soon as the
; unit starts. This allows unbound to store its pidfile. The directory and
; its content are automatically removed by systemd when the unit stops.
;
; - `NoNewPrivileges=yes` ensures that the service process and all its
; children can never gain new privileges through execve().
;
; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID
; (SUID) or set-group-ID (SGID) bits on files or directories will be denied.
;
; - `RestrictRealTime=yes` ensures that any attempts to enable realtime
; scheduling in a process invoked by the unit will be denied.
;
; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing
; is prohibited.
;
; - `LockPersonality=yes` locks down the personality system call so that the
; kernel execution domain may not be changed from the default.
;
; - With /etc/systemd/network/*.network a setting to make sure the network
; is not considered online too early, can reduce network unreachable
; errors on server start:
; [Link]
; RequiredForOnline=routable
;
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Wants=network-online.target
Before=nss-lookup.target
After=network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
[Install]
WantedBy=multi-user.target
[Service]
ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
ProtectClock=true
ProtectControlGroups=true
ProtectKernelLogs=true
ProtectKernelModules=true
# This breaks using socket options like 'so-rcvbuf'. Explicitly disable for visibility.
ProtectKernelTunables=false
ProtectProc=invisible
ProtectKernelTunables=true
ProtectSystem=strict
RuntimeDirectory=unbound
ConfigurationDirectory=unbound
StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
ReadWritePaths=@UNBOUND_SYSCONF_DIR@ @UNBOUND_LOCALSTATE_DIR@ /run @UNBOUND_RUN_DIR@
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
RestrictNamespaces=yes
LockPersonality=yes
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 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
BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
+7 -13
View File
@@ -1,14 +1,15 @@
Summary: Validating, recursive, and caching DNS resolver
Name: unbound
Version: 1.13.1
Version: 1.4.18
Release: 1%{?dist}
License: BSD
Url: http://www.nlnetlabs.nl/unbound/
Source: http://www.nlnetlabs.nl/downloads/unbound/%{name}-%{version}.tar.gz
Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
#Source1: unbound.init
Group: System Environment/Daemons
Requires: ldns
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: flex, openssl-devel, expat-devel
BuildRequires: flex, openssl-devel, expat-devel, ldns-devel
%description
Unbound is a validating, recursive, and caching DNS resolver.
@@ -41,7 +42,7 @@ install -d 0700 %{buildroot}%{_localstatedir}/%{name}
install -d 0755 %{buildroot}%{_initrddir}
install -m 0755 contrib/unbound.init %{buildroot}%{_initrddir}/unbound
# add symbolic link from /etc/unbound.conf -> /var/unbound/unbound.conf
ln -s ../%{_localstatedir}/unbound/unbound.conf %{buildroot}%{_sysconfdir}/unbound.conf
ln -s %{_localstatedir}/unbound/unbound.conf %{buildroot}%{_sysconfdir}/unbound.conf
# remove static library from install (fedora packaging guidelines)
rm -f %{buildroot}%{_libdir}/libunbound.a %{buildroot}%{_libdir}/libunbound.la
@@ -54,12 +55,11 @@ rm -rf ${RPM_BUILD_ROOT}
%attr(0755,root,root) %{_initrddir}/%{name}
%attr(0700,%{name},%{name}) %dir %{_localstatedir}/%{name}
%attr(0644,%{name},%{name}) %config(noreplace) %{_localstatedir}/%{name}/unbound.conf
%config(noreplace) %{_sysconfdir}/unbound.conf
%attr(0644,%{name},%{name}) %config(noreplace) %{_sysconfdir}/unbound.conf
%{_sbindir}/*
%{_mandir}/*/*
%{_includedir}/*
%{_libdir}/libunbound*
%{_libdir}/pkgconfig/libunbound*
%pre
getent group unbound >/dev/null || groupadd -r unbound
@@ -89,13 +89,7 @@ if [ "$1" -ge "1" ]; then
fi
%changelog
* Thu Jun 10 2021 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.13.1
- ldns and ldns-devel no longer required. Fixed date. Version to 1.13.1.
- Removed symlink attr mode, made unbound.conf symlink relative.
- Added pkgconfig/libunbound.pc to the packaged files.
- fixed download url to nlnetlabs.nl download.
* Wed Jul 13 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
* Thu Jul 13 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
- ldns required and ldns-devel required for build, no more ldns-builtin.
* Thu Mar 17 2011 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.4.8
+37 -44
View File
@@ -14,6 +14,7 @@
# Run the command unbound-control-setup to generate the key files.
#
# Environment variables for this script
# statefile - where to put temporary statefile.
# unbound_conf - where the unbound.conf file is located.
# unbound_control - where to find unbound-control executable.
# spoof_warn - what level to warn about spoofing
@@ -23,6 +24,7 @@
# with:
# [unbound*]
# user root
# env.statefile /usr/local/var/munin/plugin-state/unbound-state
# env.unbound_conf /usr/local/etc/unbound/unbound.conf
# env.unbound_control /usr/local/sbin/unbound-control
# env.spoof_warn 1000
@@ -64,6 +66,7 @@ System with unbound daemon.
[unbound*]
user root
env.statefile /usr/local/var/munin/plugin-state/unbound-state
env.unbound_conf /usr/local/etc/unbound/unbound.conf
env.unbound_control /usr/local/sbin/unbound-control
env.spoof_warn 1000
@@ -95,8 +98,7 @@ BSD
=cut
state="${MUNIN_PLUGSTATE}/unbound.state"
seentags="${MUNIN_PLUGSTATE}/unbound-seentags.state"
state=${statefile:-/usr/local/var/munin/plugin-state/unbound-state}
conf=${unbound_conf:-/usr/local/etc/unbound/unbound.conf}
ctrl=${unbound_control:-/usr/local/sbin/unbound-control}
warn=${spoof_warn:-1000}
@@ -119,24 +121,12 @@ get_value ( ) {
fi
}
# Update list of seen query types etc to seentags file. This is run while
# holding the lock, after the state file is updated.
update_seentags() {
tmplist="$(cat ${seentags} 2> /dev/null)
num.query.type.A
num.query.class.IN
num.query.opcode.QUERY
num.answer.rcode.NOERROR
"
(echo "${tmplist}"; grep ^num ${state} | sed -e 's/=.*//') | sort -u > ${seentags}
}
# download the state from the unbound server.
get_state ( ) {
# obtain lock for fetching the state
# because there is a race condition in fetching and writing to file
# see if the lock is stale, if so, take it
# see if the lock is stale, if so, take it
if test -f $lock ; then
pid="`cat $lock 2>&1`"
kill -0 "$pid" >/dev/null 2>&1
@@ -178,18 +168,17 @@ get_state ( ) {
rm -f $lock
exit 1
fi
update_seentags
rm -f $lock
}
if test "$1" = "autoconf" ; then
if test ! -f $conf; then
echo no "($conf does not exist)"
exit 0
exit 1
fi
if test ! -d `dirname $state`; then
echo no "(`dirname $state` directory does not exist)"
exit 0
exit 1
fi
echo yes
exit 0
@@ -243,7 +232,7 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
echo "graph_category DNS"
for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
sed -e 's/=.*//'`; do
exist_config $x "queries handled by `basename $x .num.queries`"
@@ -253,9 +242,6 @@ if test "$1" = "config" ; then
p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
p_config "num.query.udpout" "UDP out queries" "ABSOLUTE"
p_config "num.query.tls" "TLS queries" "ABSOLUTE"
p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
@@ -268,7 +254,7 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel number of queries"
echo "graph_scale no"
echo "graph_category dns"
echo "graph_category DNS"
p_config "total.requestlist.avg" "Average size of queue on insert" "GAUGE"
p_config "total.requestlist.max" "Max size of queue (in 5 min)" "GAUGE"
p_config "total.requestlist.overwritten" "Number of queries replaced by new ones" "GAUGE"
@@ -279,7 +265,7 @@ if test "$1" = "config" ; then
echo "graph_title Unbound memory usage"
echo "graph_args --base 1024 -l 0"
echo "graph_vlabel memory used in bytes"
echo "graph_category dns"
echo "graph_category DNS"
p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
p_config "mem.cache.message" "Message cache memory" "GAUGE"
p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
@@ -295,8 +281,9 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
for nm in `grep "^num.query.type" $seentags`; do
echo "graph_category DNS"
for x in `grep "^num.query.type" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
tp=`echo $nm | sed -e s/num.query.type.//`
p_config "$nm" "$tp" "ABSOLUTE"
done
@@ -307,8 +294,9 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
for nm in `grep "^num.query.class" $seentags`; do
echo "graph_category DNS"
for x in `grep "^num.query.class" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
tp=`echo $nm | sed -e s/num.query.class.//`
p_config "$nm" "$tp" "ABSOLUTE"
done
@@ -319,8 +307,9 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
for nm in `grep "^num.query.opcode" $seentags`; do
echo "graph_category DNS"
for x in `grep "^num.query.opcode" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
tp=`echo $nm | sed -e s/num.query.opcode.//`
p_config "$nm" "$tp" "ABSOLUTE"
done
@@ -331,8 +320,9 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel answer packets / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
for nm in `grep "^num.answer.rcode" $seentags`; do
echo "graph_category DNS"
for x in `grep "^num.answer.rcode" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
tp=`echo $nm | sed -e s/num.answer.rcode.//`
p_config "$nm" "$tp" "ABSOLUTE"
done
@@ -346,7 +336,7 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
echo "graph_category DNS"
p_config "num.query.flags.QR" "QR (query reply) flag" "ABSOLUTE"
p_config "num.query.flags.AA" "AA (auth answer) flag" "ABSOLUTE"
p_config "num.query.flags.TC" "TC (truncated) flag" "ABSOLUTE"
@@ -364,7 +354,7 @@ if test "$1" = "config" ; then
echo "graph_args --base 1000 -l 0"
echo "graph_vlabel queries / \${graph_period}"
echo "graph_scale no"
echo "graph_category dns"
echo "graph_category DNS"
echo hcache.label "cache hits"
echo hcache.min 0
echo hcache.type ABSOLUTE
@@ -453,8 +443,7 @@ hits)
for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
sed -e 's/=.*//'` total.num.queries \
total.num.cachehits total.num.prefetch num.query.tcp \
num.query.tcpout num.query.udpout num.query.tls num.query.tls.resume \
num.query.ipv6 unwanted.queries \
num.query.tcpout num.query.ipv6 unwanted.queries \
unwanted.replies; do
if grep "^"$x"=" $state >/dev/null 2>&1; then
print_value $x
@@ -475,23 +464,27 @@ memory)
done
;;
by_type)
for nm in `grep "^num.query.type" $seentags`; do
print_value $nm
for x in `grep "^num.query.type" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
print_value_line $nm $x
done
;;
by_class)
for nm in `grep "^num.query.class" $seentags`; do
print_value $nm
for x in `grep "^num.query.class" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
print_value_line $nm $x
done
;;
by_opcode)
for nm in `grep "^num.query.opcode" $seentags`; do
print_value $nm
for x in `grep "^num.query.opcode" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
print_value_line $nm $x
done
;;
by_rcode)
for nm in `grep "^num.answer.rcode" $seentags`; do
print_value $nm
for x in `grep "^num.answer.rcode" $state`; do
nm=`echo $x | sed -e 's/=.*$//'`
print_value_line $nm $x
done
print_value "num.answer.secure"
print_value "num.answer.bogus"
-49
View File
@@ -1,49 +0,0 @@
; This unit file is provided to run unbound as portable service.
; https://systemd.io/PORTABLE_SERVICES/
;
; To use this unit file, please make sure you either compile unbound with the
; following options:
;
; - --with-chroot-dir=""
;
; Or put the following options in your unbound configuration file:
;
; - chroot: ""
;
;
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Before=nss-lookup.target
Wants=nss-lookup.target
[Install]
WantedBy=multi-user.target
[Service]
ExecReload=+/bin/kill -HUP $MAINPID
ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
NotifyAccess=main
Type=notify
CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_ADMIN
MemoryDenyWriteExecute=true
NoNewPrivileges=true
PrivateDevices=true
PrivateTmp=true
ProtectHome=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectSystem=strict
RuntimeDirectory=unbound
ConfigurationDirectory=unbound
StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictRealtime=true
SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
RestrictNamespaces=yes
LockPersonality=yes
RestrictSUIDSGID=yes
BindPaths=/run/systemd/notify
BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
Binary file not shown.
Binary file not shown.
+88 -428
View File
@@ -46,10 +46,9 @@
#include "util/config_file.h"
#include "util/net_help.h"
#include "services/localzone.h"
#include "services/listen_dnsport.h"
#include "sldns/str2wire.h"
struct acl_list*
struct acl_list*
acl_list_create(void)
{
struct acl_list* acl = (struct acl_list*)calloc(1,
@@ -64,10 +63,10 @@ acl_list_create(void)
return acl;
}
void
void
acl_list_delete(struct acl_list* acl)
{
if(!acl)
if(!acl)
return;
regional_destroy(acl->region);
free(acl);
@@ -75,8 +74,8 @@ acl_list_delete(struct acl_list* acl)
/** insert new address into acl_list structure */
static struct acl_addr*
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
int complain_duplicates)
{
struct acl_addr* node = regional_alloc_zero(acl->region,
@@ -91,33 +90,6 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
return node;
}
/** parse str to acl_access enum */
static int
parse_acl_access(const char* str, enum acl_access* control)
{
if(strcmp(str, "allow") == 0)
*control = acl_allow;
else if(strcmp(str, "deny") == 0)
*control = acl_deny;
else if(strcmp(str, "refuse") == 0)
*control = acl_refuse;
else if(strcmp(str, "deny_non_local") == 0)
*control = acl_deny_non_local;
else if(strcmp(str, "refuse_non_local") == 0)
*control = acl_refuse_non_local;
else if(strcmp(str, "allow_snoop") == 0)
*control = acl_allow_snoop;
else if(strcmp(str, "allow_setrd") == 0)
*control = acl_allow_setrd;
else if (strcmp(str, "allow_cookie") == 0)
*control = acl_allow_cookie;
else {
log_err("access control type %s unknown", str);
return 0;
}
return 1;
}
/** apply acl_list string */
static int
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
@@ -127,14 +99,29 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
int net;
socklen_t addrlen;
enum acl_access control;
if(!parse_acl_access(s2, &control)) {
if(strcmp(s2, "allow") == 0)
control = acl_allow;
else if(strcmp(s2, "deny") == 0)
control = acl_deny;
else if(strcmp(s2, "refuse") == 0)
control = acl_refuse;
else if(strcmp(s2, "deny_non_local") == 0)
control = acl_deny_non_local;
else if(strcmp(s2, "refuse_non_local") == 0)
control = acl_refuse_non_local;
else if(strcmp(s2, "allow_snoop") == 0)
control = acl_allow_snoop;
else if(strcmp(s2, "allow_setrd") == 0)
control = acl_allow_setrd;
else {
log_err("access control type %s unknown", str);
return 0;
}
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse access control: %s %s", str, s2);
return 0;
}
if(!acl_list_insert(acl, &addr, addrlen, net, control,
if(!acl_list_insert(acl, &addr, addrlen, net, control,
complain_duplicates)) {
log_err("out of memory");
return 0;
@@ -144,27 +131,19 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
/** find or create node (NULL on parse or error) */
static struct acl_addr*
acl_find_or_create_str2addr(struct acl_list* acl, const char* str,
int is_interface, int port)
acl_find_or_create(struct acl_list* acl, const char* str)
{
struct acl_addr* node;
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
int net = (str_is_ip6(str)?128:32);
if(is_interface) {
if(!extstrtoaddr(str, &addr, &addrlen, port)) {
log_err("cannot parse interface: %s", str);
return NULL;
}
} else {
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse netblock: %s", str);
return NULL;
}
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse netblock: %s", str);
return NULL;
}
/* find or create node */
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
addrlen, net)) && !is_interface) {
addrlen, net))) {
/* create node, type 'allow' since otherwise tags are
* pointless, can override with specific access-control: cfg */
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
@@ -176,67 +155,14 @@ acl_find_or_create_str2addr(struct acl_list* acl, const char* str,
return node;
}
/** find or create node (NULL on error) */
static struct acl_addr*
acl_find_or_create(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access control)
{
struct acl_addr* node;
int net = (addr_is_ip6(addr, addrlen)?128:32);
/* find or create node */
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, addr,
addrlen, net))) {
/* create node;
* can override with specific access-control: cfg */
if(!(node=(struct acl_addr*)acl_list_insert(acl, addr,
addrlen, net, control, 1))) {
log_err("out of memory");
return NULL;
}
}
return node;
}
/** apply acl_interface string */
static int
acl_interface_str_cfg(struct acl_list* acl_interface, const char* iface,
const char* s2, int port)
{
struct acl_addr* node;
enum acl_access control;
if(!parse_acl_access(s2, &control)) {
return 0;
}
if(!(node=acl_find_or_create_str2addr(acl_interface, iface, 1, port))) {
log_err("cannot update ACL on non-configured interface: %s %d",
iface, port);
return 0;
}
node->control = control;
return 1;
}
struct acl_addr*
acl_interface_insert(struct acl_list* acl_interface,
struct sockaddr_storage* addr, socklen_t addrlen,
enum acl_access control)
{
struct acl_addr* node = acl_find_or_create(acl_interface, addr, addrlen, control);
node->is_interface = 1;
return node;
}
/** apply acl_tag string */
static int
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
size_t bitmaplen, int is_interface, int port)
size_t bitmaplen)
{
struct acl_addr* node;
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
if(!(node=acl_find_or_create(acl, str)))
return 0;
}
node->taglen = bitmaplen;
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
if(!node->taglist) {
@@ -249,14 +175,11 @@ acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
/** apply acl_view string */
static int
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
struct views* vs, int is_interface, int port)
struct views* vs)
{
struct acl_addr* node;
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
if(!(node=acl_find_or_create(acl, str)))
return 0;
}
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
if(!node->view) {
log_err("no view with name: %s", str2);
@@ -269,17 +192,13 @@ acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
/** apply acl_tag_action string */
static int
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
const char* str, const char* tag, const char* action,
int is_interface, int port)
const char* str, const char* tag, const char* action)
{
struct acl_addr* node;
int tagid;
enum localzone_type t;
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
if(!(node=acl_find_or_create(acl, str)))
return 0;
}
/* allocate array if not yet */
if(!node->tag_actions) {
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
@@ -354,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)-2,
(int)LDNS_WIREPARSE_OFFSET(res)-13,
sldns_get_errorstr_parse(res));
return 0;
}
@@ -362,17 +281,13 @@ check_data(const char* data, const struct config_strlist* head)
/** apply acl_tag_data string */
static int
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
const char* str, const char* tag, const char* data,
int is_interface, int port)
const char* str, const char* tag, const char* data)
{
struct acl_addr* node;
int tagid;
char* dupdata;
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
if(is_interface)
log_err("non-configured interface: %s", str);
if(!(node=acl_find_or_create(acl, str)))
return 0;
}
/* allocate array if not yet */
if(!node->tag_datas) {
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
@@ -414,11 +329,11 @@ acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
}
/** read acl_list config */
static int
read_acl_list(struct acl_list* acl, struct config_str2list* acls)
static int
read_acl_list(struct acl_list* acl, struct config_file* cfg)
{
struct config_str2list* p;
for(p = acls; p; p = p->next) {
for(p = cfg->acls; p; p = p->next) {
log_assert(p->str && p->str2);
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
return 0;
@@ -426,38 +341,15 @@ read_acl_list(struct acl_list* acl, struct config_str2list* acls)
return 1;
}
/** read acl view config */
static int
read_acl_view(struct acl_list* acl, struct config_str2list** acl_view,
struct views* v)
{
struct config_str2list* np, *p = *acl_view;
*acl_view = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_view_cfg(acl, p->str, p->str2, v, 0, 0)) {
config_deldblstrlist(p);
return 0;
}
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tags config */
static int
read_acl_tags(struct acl_list* acl, struct config_strbytelist** acl_tags)
static int
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
{
struct config_strbytelist* np, *p = *acl_tags;
*acl_tags = NULL;
struct config_strbytelist* np, *p = cfg->acl_tags;
cfg->acl_tags = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len, 0, 0)) {
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
config_del_strbytelist(p);
return 0;
}
@@ -471,18 +363,38 @@ read_acl_tags(struct acl_list* acl, struct config_strbytelist** acl_tags)
return 1;
}
/** read acl view config */
static int
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
{
struct config_str2list* np, *p = cfg->acl_view;
cfg->acl_view = NULL;
while(p) {
log_assert(p->str && p->str2);
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
return 0;
}
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tag actions config */
static int
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg,
struct config_str3list** acl_tag_actions)
static int
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
{
struct config_str3list* p, *np;
p = *acl_tag_actions;
*acl_tag_actions = NULL;
p = cfg->acl_tag_actions;
cfg->acl_tag_actions = NULL;
while(p) {
log_assert(p->str && p->str2 && p->str3);
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
p->str3, 0, 0)) {
p->str3)) {
config_deltrplstrlist(p);
return 0;
}
@@ -498,17 +410,15 @@ read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg,
}
/** read acl tag datas config */
static int
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg,
struct config_str3list** acl_tag_datas)
static int
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
{
struct config_str3list* p, *np;
p = *acl_tag_datas;
*acl_tag_datas = NULL;
p = cfg->acl_tag_datas;
cfg->acl_tag_datas = NULL;
while(p) {
log_assert(p->str && p->str2 && p->str3);
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3,
0, 0)) {
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
config_deltrplstrlist(p);
return 0;
}
@@ -523,27 +433,30 @@ read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg,
return 1;
}
int
int
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v)
{
regional_free_all(acl->region);
addr_tree_init(&acl->tree);
if(!read_acl_list(acl, cfg->acls))
if(!read_acl_list(acl, cfg))
return 0;
if(!read_acl_view(acl, &cfg->acl_view, v))
if(!read_acl_view(acl, cfg, v))
return 0;
if(!read_acl_tags(acl, &cfg->acl_tags))
if(!read_acl_tags(acl, cfg))
return 0;
if(!read_acl_tag_actions(acl, cfg, &cfg->acl_tag_actions))
if(!read_acl_tag_actions(acl, cfg))
return 0;
if(!read_acl_tag_datas(acl, cfg, &cfg->acl_tag_datas))
if(!read_acl_tag_datas(acl, cfg))
return 0;
/* insert defaults, with '0' to ignore them if they are duplicates */
/* the 'refuse' defaults for /0 are now done per interface instead */
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
return 0;
if(cfg->do_ip6) {
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
return 0;
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
@@ -553,212 +466,7 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
return 1;
}
void
acl_interface_init(struct acl_list* acl_interface)
{
regional_free_all(acl_interface->region);
/* We want comparison in the tree to include only address and port.
* We don't care about comparing node->net. All addresses in the
* acl_interface->tree should have either 32 (ipv4) or 128 (ipv6).
* Initialise with the appropriate compare function but keep treating
* it as an addr_tree. */
addr_tree_addrport_init(&acl_interface->tree);
}
static int
read_acl_interface_action(struct acl_list* acl_interface,
struct config_str2list* acls, int port)
{
struct config_str2list* p;
for(p = acls; p; p = p->next) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif))
return 0;
for(i = 0; i<num_resif; i++) {
if(!acl_interface_str_cfg(acl_interface, resif[i], p->str2, port)){
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
}
return 1;
}
/** read acl view config for interface */
static int
read_acl_interface_view(struct acl_list* acl_interface,
struct config_str2list** acl_view,
struct views* v, int port)
{
struct config_str2list* np, *p = *acl_view;
*acl_view = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deldblstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_view_cfg(acl_interface, resif[i], p->str2,
v, 1, port)) {
config_del_strarray(resif, num_resif);
config_deldblstrlist(p);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tags config for interface */
static int
read_acl_interface_tags(struct acl_list* acl_interface,
struct config_strbytelist** acl_tags, int port)
{
struct config_strbytelist* np, *p = *acl_tags;
*acl_tags = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_del_strbytelist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tags_cfg(acl_interface, resif[i], p->str2,
p->str2len, 1, port)) {
config_del_strbytelist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
return 1;
}
/** read acl tag actions config for interface*/
static int
read_acl_interface_tag_actions(struct acl_list* acl_interface,
struct config_file* cfg,
struct config_str3list** acl_tag_actions, int port)
{
struct config_str3list* p, *np;
p = *acl_tag_actions;
*acl_tag_actions = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2 && p->str3);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deltrplstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tag_action_cfg(acl_interface, cfg,
resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p->str3);
free(p);
p = np;
}
return 1;
}
/** read acl tag datas config for interface */
static int
read_acl_interface_tag_datas(struct acl_list* acl_interface,
struct config_file* cfg,
struct config_str3list** acl_tag_datas, int port)
{
struct config_str3list* p, *np;
p = *acl_tag_datas;
*acl_tag_datas = NULL;
while(p) {
char** resif = NULL;
int num_resif = 0;
int i;
log_assert(p->str && p->str2 && p->str3);
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
config_deltrplstrlist(p);
return 0;
}
for(i = 0; i<num_resif; i++) {
if(!acl_list_tag_data_cfg(acl_interface, cfg,
resif[i], p->str2, p->str3, 1, port)) {
config_deltrplstrlist(p);
config_del_strarray(resif, num_resif);
return 0;
}
}
config_del_strarray(resif, num_resif);
/* free the items as we go to free up memory */
np = p->next;
free(p->str);
free(p->str2);
free(p->str3);
free(p);
p = np;
}
return 1;
}
int
acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
struct views* v)
{
if(!read_acl_interface_action(acl_interface, cfg->interface_actions,
cfg->port))
return 0;
if(!read_acl_interface_view(acl_interface, &cfg->interface_view, v,
cfg->port))
return 0;
if(!read_acl_interface_tags(acl_interface, &cfg->interface_tags,
cfg->port))
return 0;
if(!read_acl_interface_tag_actions(acl_interface, cfg,
&cfg->interface_tag_actions, cfg->port))
return 0;
if(!read_acl_interface_tag_datas(acl_interface, cfg,
&cfg->interface_tag_datas, cfg->port))
return 0;
addr_tree_init_parents(&acl_interface->tree);
return 1;
}
enum acl_access
enum acl_access
acl_get_control(struct acl_addr* acl)
{
if(acl) return acl->control;
@@ -773,57 +481,9 @@ acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
addr, addrlen);
}
size_t
size_t
acl_list_get_mem(struct acl_list* acl)
{
if(!acl) return 0;
return sizeof(*acl) + regional_get_mem(acl->region);
}
const char* acl_access_to_str(enum acl_access acl)
{
switch(acl) {
case acl_deny: return "deny";
case acl_refuse: return "refuse";
case acl_deny_non_local: return "deny_non_local";
case acl_refuse_non_local: return "refuse_non_local";
case acl_allow: return "allow";
case acl_allow_snoop: return "allow_snoop";
case acl_allow_setrd: return "allow_setrd";
default: break;
}
return "unknown";
}
void
log_acl_action(const char* action, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr)
{
char a[128], n[128];
uint16_t port;
addr_to_str(addr, addrlen, a, sizeof(a));
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
if(acladdr) {
addr_to_str(&acladdr->node.addr, acladdr->node.addrlen,
n, sizeof(n));
verbose(VERB_ALGO, "%s query from %s port %d because of "
"%s/%d %s%s", action, a, (int)port, n,
acladdr->node.net,
acladdr->is_interface?"(ACL on interface IP) ":"",
acl_access_to_str(acl));
} else {
verbose(VERB_ALGO, "%s query from %s port %d", action, a,
(int)port);
}
}
void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data)
{
/* swap tree and region */
rbtree_type oldtree = acl->tree;
struct regional* oldregion = acl->region;
acl->tree = data->tree;
acl->region = data->region;
data->tree = oldtree;
data->region = oldregion;
}
+5 -60
View File
@@ -36,7 +36,7 @@
/**
* \file
*
* This file keeps track of the list of clients that are allowed to
* This file keeps track of the list of clients that are allowed to
* access the server.
*/
@@ -64,12 +64,8 @@ enum acl_access {
acl_allow,
/** allow full access for all queries, recursion and cache snooping */
acl_allow_snoop,
/** allow full access for recursion queries and set RD flag regardless
* of request */
acl_allow_setrd,
/** allow full access for recursion (+RD) queries if valid cookie
* present or stateful transport */
acl_allow_cookie
/** allow full access for recursion queries and set RD flag regardless of request */
acl_allow_setrd
};
/**
@@ -78,7 +74,7 @@ enum acl_access {
struct acl_list {
/** regional for allocation */
struct regional* region;
/**
/**
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
@@ -107,14 +103,12 @@ struct acl_addr {
struct config_strlist** tag_datas;
/** size of the tag_datas array */
size_t tag_datas_size;
/* If the acl node is for an interface */
int is_interface;
/* view element, NULL if none */
struct view* view;
};
/**
* Create acl structure
* Create acl structure
* @return new structure or NULL on error.
*/
struct acl_list* acl_list_create(void);
@@ -125,20 +119,6 @@ struct acl_list* acl_list_create(void);
*/
void acl_list_delete(struct acl_list* acl);
/**
* Insert interface in the acl_list. This should happen when the listening
* interface is setup.
* @param acl_interface: acl_list to insert to.
* @param addr: interface IP.
* @param addrlen: length of the interface IP.
* @param control: acl_access.
* @return new structure or NULL on error.
*/
struct acl_addr*
acl_interface_insert(struct acl_list* acl_interface,
struct sockaddr_storage* addr, socklen_t addrlen,
enum acl_access control);
/**
* Process access control config.
* @param acl: where to store.
@@ -149,22 +129,6 @@ acl_interface_insert(struct acl_list* acl_interface,
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
struct views* v);
/**
* Initialise (also clean) the acl_interface struct.
* @param acl_interface: where to store.
*/
void acl_interface_init(struct acl_list* acl_interface);
/**
* Process interface control config.
* @param acl_interface: where to store.
* @param cfg: config options.
* @param v: views structure
* @return 0 on error.
*/
int acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
struct views* v);
/**
* Lookup access control status for acl structure.
* @param acl: structure for acl storage.
@@ -190,23 +154,4 @@ acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
*/
size_t acl_list_get_mem(struct acl_list* acl);
/*
* Get string for acl access specification
* @param acl: access type value
* @return string
*/
const char* acl_access_to_str(enum acl_access acl);
/* log acl and addr for action */
void log_acl_action(const char* action, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr);
/**
* Swap internal tree with preallocated entries.
* @param acl: the acl structure.
* @param data: the data structure used to take elements from. This contains
* the old elements on return.
*/
void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data);
#endif /* DAEMON_ACL_LIST_H */
+123 -279
View File
@@ -47,12 +47,10 @@
#include "services/cache/rrset.h"
#include "services/cache/dns.h"
#include "services/cache/infra.h"
#include "services/outside_network.h"
#include "util/data/msgreply.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "util/config_file.h"
#include "iterator/iterator.h"
#include "iterator/iter_delegpt.h"
#include "iterator/iter_utils.h"
@@ -62,231 +60,84 @@
#include "sldns/wire2str.h"
#include "sldns/str2wire.h"
static void spool_txt_printf(struct config_strlist_head* txt,
const char* format, ...) ATTR_FORMAT(printf, 2, 3);
/** Append to strlist at end, and log error if out of memory. */
static void
spool_txt_string(struct config_strlist_head* txt, char* str)
{
if(!cfg_strlist_append(txt, strdup(str))) {
log_err("out of memory in spool text");
}
}
/** Spool txt to spool list. */
static void
spool_txt_vmsg(struct config_strlist_head* txt, const char* format,
va_list args)
{
char msg[65535];
vsnprintf(msg, sizeof(msg), format, args);
spool_txt_string(txt, msg);
}
/** Print item to spool list. On alloc failure the list is as before. */
static void
spool_txt_printf(struct config_strlist_head* txt, const char* format, ...)
{
va_list args;
va_start(args, format);
spool_txt_vmsg(txt, format, args);
va_end(args);
}
/** dump one rrset zonefile line */
static void
dump_rrset_line(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
time_t now, size_t i)
static int
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
{
char s[65535*4+2048];
char s[65535];
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
spool_txt_string(txt, "BADRR\n");
return;
return ssl_printf(ssl, "BADRR\n");
}
spool_txt_string(txt, s);
return ssl_printf(ssl, "%s", s);
}
/** dump rrset key and data info */
static void
dump_rrset(struct config_strlist_head* txt, struct ub_packed_rrset_key* k,
static int
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
struct packed_rrset_data* d, time_t now)
{
size_t i;
/* rd lock held by caller */
if(!k || !d) return;
if(k->id == 0) return; /* deleted */
if(d->ttl < now) return; /* expired */
if(!k || !d) return 1;
if(k->id == 0) return 1; /* deleted */
if(d->ttl < now) return 1; /* expired */
/* meta line */
spool_txt_printf(txt, ";rrset%s " ARG_LL "d %u %u %d %d\n",
if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
(k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
(long long)(d->ttl - now),
(unsigned)d->count, (unsigned)d->rrsig_count,
(int)d->trust, (int)d->security
);
))
return 0;
for(i=0; i<d->count + d->rrsig_count; i++) {
dump_rrset_line(txt, k, now, i);
}
}
/** Spool strlist to the output. */
static int
spool_strlist(RES* ssl, struct config_strlist* list)
{
struct config_strlist* s;
for(s=list; s; s=s->next) {
if(!ssl_printf(ssl, "%s", s->str))
if(!dump_rrset_line(ssl, k, now, i))
return 0;
}
return 1;
}
/** dump lruhash cache and call callback for every item. */
/** dump lruhash rrset cache */
static int
dump_lruhash(struct lruhash* table,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
{
int just_started = 1;
int not_done = 1;
hashvalue_type hash;
size_t num = 0; /* number of entries processed. */
size_t max = 2; /* number of entries after which it unlocks. */
struct config_strlist_head txt; /* Text strings spooled. */
memset(&txt, 0, sizeof(txt));
while(not_done) {
size_t i; /* hash bin. */
/* Process a number of items. */
num = 0;
lock_quick_lock(&table->lock);
if(just_started) {
i = 0;
} else {
i = hash&table->size_mask;
}
while(num < max) {
/* Process bin. */
int found = 0;
size_t num_bin = 0;
struct lruhash_bin* bin = &table->array[i];
struct lruhash_entry* e;
lock_quick_lock(&bin->lock);
for(e = bin->overflow_list; e; e = e->overflow_next) {
/* Entry e is locked by the func. */
func(e, &txt, arg);
num_bin++;
}
lock_quick_unlock(&bin->lock);
/* This addition of bin number of entries may take
* it over the max. */
num += num_bin;
/* Move to next bin. */
/* Find one with an entry, with a hash value, so we
* can continue from the hash value. The hash value
* can be indexed also if the array changes size. */
i++;
while(i < table->size) {
bin = &table->array[i];
lock_quick_lock(&bin->lock);
if(bin->overflow_list) {
hash = bin->overflow_list->hash;
lock_quick_unlock(&bin->lock);
found = 1;
just_started = 0;
break;
}
lock_quick_unlock(&bin->lock);
i++;
}
if(!found) {
not_done = 0;
break;
}
}
lock_quick_unlock(&table->lock);
/* Print the spooled items, that are collected while the
* locks are locked. The print happens while they are not
* locked. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
return 0;
}
config_delstrlist(txt.first);
memset(&txt, 0, sizeof(txt));
}
}
/* Print the final spooled items. */
if(txt.first) {
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
struct lruhash_entry* e;
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
lock_rw_rdlock(&e->lock);
if(!dump_rrset(ssl, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data, now)) {
lock_rw_unlock(&e->lock);
return 0;
}
config_delstrlist(txt.first);
lock_rw_unlock(&e->lock);
}
return 1;
}
/** dump slabhash cache and call callback for every item. */
static int
dump_slabhash(struct slabhash* sh,
void (*func)(struct lruhash_entry*, struct config_strlist_head*, void*),
RES* ssl, void* arg)
{
/* Process a number of items at a time, then unlock the cache,
* so that ordinary processing can continue. Keep an iteration marker
* to continue the loop. That means the cache can change, items
* could be inserted and deleted. And, for example, the hash table
* can grow. */
size_t slab;
for(slab=0; slab<sh->size; slab++) {
if(!dump_lruhash(sh->array[slab], func, ssl, arg))
return 0;
}
return 1;
}
/** Struct for dump information. */
struct dump_info {
/** The worker. */
struct worker* worker;
/** The printout connection. */
RES* ssl;
};
/** Dump the rrset cache entry */
static void
dump_rrset_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
{
struct dump_info* dump_info = (struct dump_info*)arg;
lock_rw_rdlock(&e->lock);
dump_rrset(txt, (struct ub_packed_rrset_key*)e->key,
(struct packed_rrset_data*)e->data,
*dump_info->worker->env.now);
lock_rw_unlock(&e->lock);
}
/** dump rrset cache */
static int
dump_rrset_cache(RES* ssl, struct worker* worker)
{
struct rrset_cache* r = worker->env.rrset_cache;
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
size_t slab;
if(!ssl_printf(ssl, "START_RRSET_CACHE\n")) return 0;
if(!dump_slabhash(&r->table, &dump_rrset_entry, ssl, &dump_info))
return 0;
for(slab=0; slab<r->table.size; slab++) {
lock_quick_lock(&r->table.array[slab]->lock);
if(!dump_rrset_lruhash(ssl, r->table.array[slab],
*worker->env.now)) {
lock_quick_unlock(&r->table.array[slab]->lock);
return 0;
}
lock_quick_unlock(&r->table.array[slab]->lock);
}
return ssl_printf(ssl, "END_RRSET_CACHE\n");
}
/** dump message to rrset reference */
static void
dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
static int
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
{
char* nm, *tp, *cl;
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
@@ -296,25 +147,31 @@ dump_msg_ref(struct config_strlist_head* txt, struct ub_packed_rrset_key* k)
free(nm);
free(tp);
free(cl);
spool_txt_string(txt, "BADREF\n");
return;
return ssl_printf(ssl, "BADREF\n");
}
if(!ssl_printf(ssl, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags)) {
free(nm);
free(tp);
free(cl);
return 0;
}
spool_txt_printf(txt, "%s %s %s %d\n", nm, cl, tp, (int)k->rk.flags);
free(nm);
free(tp);
free(cl);
return 1;
}
/** dump message entry */
static void
dump_msg(struct config_strlist_head* txt, struct query_info* k,
struct reply_info* d, time_t now)
static int
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
time_t now)
{
size_t i;
char* nm, *tp, *cl;
if(!k || !d) return;
if(d->ttl < now) return; /* expired */
if(!k || !d) return 1;
if(d->ttl < now) return 1; /* expired */
nm = sldns_wire2str_dname(k->qname, k->qname_len);
tp = sldns_wire2str_type(k->qtype);
cl = sldns_wire2str_class(k->qclass);
@@ -322,35 +179,43 @@ dump_msg(struct config_strlist_head* txt, struct query_info* k,
free(nm);
free(tp);
free(cl);
return; /* skip this entry */
return 1; /* skip this entry */
}
if(!rrset_array_lock(d->ref, d->rrset_count, now)) {
/* rrsets have timed out or do not exist */
free(nm);
free(tp);
free(cl);
return; /* skip this entry */
return 1; /* skip this entry */
}
/* meta line */
spool_txt_printf(txt,
"msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets,
(int)d->reason_bogus,
d->reason_bogus_str?d->reason_bogus_str:"");
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u\n",
nm, cl, tp,
(int)d->flags, (int)d->qdcount,
(long long)(d->ttl-now), (int)d->security,
(unsigned)d->an_numrrsets,
(unsigned)d->ns_numrrsets,
(unsigned)d->ar_numrrsets)) {
free(nm);
free(tp);
free(cl);
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
free(nm);
free(tp);
free(cl);
for(i=0; i<d->rrset_count; i++) {
dump_msg_ref(txt, d->rrsets[i]);
if(!dump_msg_ref(ssl, d->rrsets[i])) {
rrset_array_unlock(d->ref, d->rrset_count);
return 0;
}
}
rrset_array_unlock(d->ref, d->rrset_count);
return 1;
}
/** copy msg to worker pad */
@@ -379,40 +244,49 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
return (*k)->qname != NULL;
}
/** Dump the msg entry. */
static void
dump_msg_entry(struct lruhash_entry* e, struct config_strlist_head* txt,
void* arg)
/** dump lruhash msg cache */
static int
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
{
struct dump_info* dump_info = (struct dump_info*)arg;
struct lruhash_entry* e;
struct query_info* k;
struct reply_info* d;
regional_free_all(dump_info->worker->scratchpad);
/* Make copy of rrset in worker buffer. */
lock_rw_rdlock(&e->lock);
if(!copy_msg(dump_info->worker->scratchpad, e, &k, &d)) {
/* lruhash already locked by caller */
/* walk in order of lru; best first */
for(e=h->lru_start; e; e = e->lru_next) {
regional_free_all(worker->scratchpad);
lock_rw_rdlock(&e->lock);
/* make copy of rrset in worker buffer */
if(!copy_msg(worker->scratchpad, e, &k, &d)) {
lock_rw_unlock(&e->lock);
return 0;
}
lock_rw_unlock(&e->lock);
log_err("out of memory in dump_msg_entry");
return;
/* release lock so we can lookup the rrset references
* in the rrset cache */
if(!dump_msg(ssl, k, d, *worker->env.now)) {
return 0;
}
}
lock_rw_unlock(&e->lock);
/* Release lock so we can lookup the rrset references
* in the rrset cache. */
dump_msg(txt, k, d, *dump_info->worker->env.now);
return 1;
}
/** dump msg cache */
static int
dump_msg_cache(RES* ssl, struct worker* worker)
{
struct dump_info dump_info;
dump_info.worker = worker;
dump_info.ssl = ssl;
struct slabhash* sh = worker->env.msg_cache;
size_t slab;
if(!ssl_printf(ssl, "START_MSG_CACHE\n")) return 0;
if(!dump_slabhash(worker->env.msg_cache, &dump_msg_entry, ssl,
&dump_info))
return 0;
for(slab=0; slab<sh->size; slab++) {
lock_quick_lock(&sh->array[slab]->lock);
if(!dump_msg_lruhash(ssl, worker, sh->array[slab])) {
lock_quick_unlock(&sh->array[slab]->lock);
return 0;
}
lock_quick_unlock(&sh->array[slab]->lock);
}
return ssl_printf(ssl, "END_MSG_CACHE\n");
}
@@ -455,7 +329,7 @@ load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
/* read the line */
if(!ssl_read_buf(ssl, buf))
return 0;
if(strcmp((char*)sldns_buffer_begin(buf), "BADRR") == 0) {
if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
*go_on = 0;
return 1;
}
@@ -511,7 +385,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
struct rrset_ref ref;
uint8_t* p;
ak = alloc_special_obtain(worker->alloc);
ak = alloc_special_obtain(&worker->alloc);
if(!ak) {
log_warn("error out of memory");
return 0;
@@ -522,7 +396,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
if(!ak->rk.dname) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, worker->alloc);
ub_packed_rrset_parsedelete(ak, &worker->alloc);
return 0;
}
s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) +
@@ -532,7 +406,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ad = (struct packed_rrset_data*)malloc(s);
if(!ad) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, worker->alloc);
ub_packed_rrset_parsedelete(ak, &worker->alloc);
return 0;
}
p = (uint8_t*)ad;
@@ -555,8 +429,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ref.key = ak;
ref.id = ak->id;
(void)rrset_cache_update(worker->env.rrset_cache, &ref,
worker->alloc, *worker->env.now);
&worker->alloc, *worker->env.now);
return 1;
}
@@ -757,9 +630,6 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
long long ttl;
size_t i;
int go_on = 1;
int ede;
int consumed = 0;
char* ede_str = NULL;
regional_free_all(region);
@@ -774,16 +644,11 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
}
/* read remainder of line */
/* note the last space before any possible EDE text */
if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u %d %n", &flags, &qdcount, &ttl,
&security, &an, &ns, &ar, &ede, &consumed) != 8) {
if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u", &flags, &qdcount, &ttl,
&security, &an, &ns, &ar) != 7) {
log_warn("error cannot parse numbers: %s", s);
return 0;
}
/* there may be EDE text after the numbers */
if(consumed > 0 && (size_t)consumed < strlen(s))
ede_str = s + consumed;
memset(&rep, 0, sizeof(rep));
rep.flags = (uint16_t)flags;
rep.qdcount = (uint16_t)qdcount;
rep.ttl = (time_t)ttl;
@@ -798,8 +663,6 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
rep.ns_numrrsets = (size_t)ns;
rep.ar_numrrsets = (size_t)ar;
rep.rrset_count = (size_t)an+(size_t)ns+(size_t)ar;
rep.reason_bogus = (sldns_ede_code)ede;
rep.reason_bogus_str = ede_str?(char*)regional_strdup(region, ede_str):NULL;
rep.rrsets = (struct ub_packed_rrset_key**)regional_alloc_zero(
region, sizeof(struct ub_packed_rrset_key*)*rep.rrset_count);
@@ -814,8 +677,7 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
if(!go_on)
return 1; /* skip this one, not all references satisfied */
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags,
*worker->env.now, 1)) {
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) {
log_warn("error out of memory");
return 0;
}
@@ -934,18 +796,12 @@ print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
struct packed_rrset_data* d =
(struct packed_rrset_data*)k->entry.data;
struct config_strlist_head txt;
memset(&txt, 0, sizeof(txt));
if(d->security == sec_status_bogus) {
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
return;
}
dump_rrset(&txt, k, d, 0);
if(!spool_strlist(ssl, txt.first)) {
config_delstrlist(txt.first);
if(!dump_rrset(ssl, k, d, 0))
return;
}
config_delstrlist(txt.first);
}
delegpt_count_ns(dp, &n_ns, &n_miss);
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
@@ -965,10 +821,9 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
struct delegpt* dp;
struct dns_msg* msg;
struct regional* region = worker->scratchpad;
char b[LDNS_MAX_DOMAINLEN];
char b[260];
struct query_info qinfo;
struct iter_hints_stub* stub;
int nolock = 0;
regional_free_all(region);
qinfo.qname = nm;
qinfo.qname_len = nmlen;
@@ -980,32 +835,26 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
if(!ssl_printf(ssl, "The following name servers are used for lookup "
"of %s\n", b))
return 0;
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass, nolock);
dp = forwards_lookup(worker->env.fwds, nm, qinfo.qclass);
if(dp) {
if(!ssl_printf(ssl, "forwarding request:\n")) {
lock_rw_unlock(&worker->env.fwds->lock);
if(!ssl_printf(ssl, "forwarding request:\n"))
return 0;
}
print_dp_main(ssl, dp, NULL);
print_dp_details(ssl, worker, dp);
lock_rw_unlock(&worker->env.fwds->lock);
return 1;
}
while(1) {
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
qinfo.qtype, qinfo.qclass, region, &msg,
*worker->env.now, 0, NULL, 0);
*worker->env.now);
if(!dp) {
return ssl_printf(ssl, "no delegation from "
"cache; goes to configured roots\n");
}
/* go up? */
if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
(worker->env.cfg->do_ip4 && worker->back->num_ip4 != 0),
(worker->env.cfg->do_ip6 && worker->back->num_ip6 != 0),
worker->env.cfg->do_nat64)) {
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
print_dp_main(ssl, dp, msg);
print_dp_details(ssl, worker, dp);
if(!ssl_printf(ssl, "cache delegation was "
@@ -1025,26 +874,21 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
return 0;
continue;
}
}
}
stub = hints_lookup_stub(worker->env.hints, nm, qinfo.qclass,
dp, nolock);
dp);
if(stub) {
if(stub->noprime) {
if(!ssl_printf(ssl, "The noprime stub servers "
"are used:\n")) {
lock_rw_unlock(&worker->env.hints->lock);
"are used:\n"))
return 0;
}
} else {
if(!ssl_printf(ssl, "The stub is primed "
"with servers:\n")) {
lock_rw_unlock(&worker->env.hints->lock);
"with servers:\n"))
return 0;
}
}
print_dp_main(ssl, stub->dp, NULL);
print_dp_details(ssl, worker, stub->dp);
lock_rw_unlock(&worker->env.hints->lock);
} else {
print_dp_main(ssl, dp, msg);
print_dp_details(ssl, worker, dp);
+56 -614
View File
File diff suppressed because it is too large Load Diff
+6 -100
View File
@@ -58,11 +58,6 @@ struct ub_randstate;
struct daemon_remote;
struct respip_set;
struct shm_main_info;
struct doq_table;
struct cookie_secrets;
struct fast_reload_thread;
struct fast_reload_printq;
struct shared_ports;
#include "dnstap/dnstap_config.h"
#ifdef USE_DNSTAP
@@ -98,38 +93,14 @@ struct daemon {
int rc_port;
/** listening ports for remote control */
struct listen_port* rc_ports;
/** the shared ports structure, with random ports numbers. */
struct shared_ports* shared_ports;
/** remote control connections management (for first worker) */
struct daemon_remote* rc;
/** ssl context for listening to dnstcp over ssl */
void* listen_dot_sslctx;
/** ssl context for connecting to dnstcp over ssl */
void* connect_dot_sslctx;
/** ssl context for listening to DoH */
void* listen_doh_sslctx;
/** ssl context for listening to quic */
void* listen_quic_sslctx;
/** the file name that the ssl context is made with, private key. */
char* ssl_service_key;
/** the file name that the ssl context is made with, certificate. */
char* ssl_service_pem;
/** modification time for ssl_service_key, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_key;
long mtime_ns_ssl_service_key;
/** modification time for ssl_service_pem, in sec and ns. Like
* in a struct timespec, but without that for portability. */
time_t mtime_ssl_service_pem;
long mtime_ns_ssl_service_pem;
/** ssl context for listening to dnstcp over ssl, and connecting ssl */
void* listen_sslctx, *connect_sslctx;
/** num threads allocated */
int num;
/** num threads allocated in the previous config or 0 at first */
int old_num;
/** the worker entries */
struct worker** workers;
/** per-worker allocation cache */
struct alloc_cache **worker_allocs;
/** do we need to exit unbound (or is it only a reload?) */
int need_to_exit;
/** master random table ; used for port div between threads on reload*/
@@ -140,12 +111,8 @@ struct daemon {
struct module_env* env;
/** stack of module callbacks */
struct module_stack mods;
/** The module stack has been inited */
int mods_inited;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** access control, which interfaces are allowed to connect */
struct acl_list* acl_interface;
/** TCP connection limit, limit connections from client IPs */
struct tcl_list* tcl;
/** local authority zones */
@@ -154,43 +121,21 @@ struct daemon {
struct timeval time_last_stat;
/** time when daemon started */
struct timeval time_boot;
/** views structure containing view tree */
struct views* views;
#ifdef USE_DNSTAP
/** the dnstap environment master value, copied and changed by threads*/
struct dt_env* dtenv;
#endif
/** The SHM info for shared memory stats. */
struct shm_main_info* shm_info;
/** if the timeout for statistics is attempted at specific offset.
* If it is true, the stat timeout is the interval+offset, and that
* picks (roughly) the same time offset every time period. */
int stat_time_specific;
/** if the timeout is specific, what offset in the period. */
int stat_time_offset;
/** response-ip set with associated actions and tags. */
struct respip_set* respip_set;
/** some response-ip tags or actions are configured if true */
int use_response_ip;
/** some RPZ policies are configured */
int use_rpz;
#ifdef USE_DNSCRYPT
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
/** the doq connection table */
struct doq_table* doq_table;
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
/** the EDNS cookie secrets from the cookie-secret-file */
struct cookie_secrets* cookie_secrets;
/** the fast reload thread, or NULL */
struct fast_reload_thread* fast_reload_thread;
/** the fast reload printq list */
struct fast_reload_printq* fast_reload_printq_list;
/** the fast reload option to drop mesh queries, true if so. */
int fast_reload_drop_mesh;
/** for fast reload, if the tcl, tcp connection limits, has
* changes for workers */
int fast_reload_tcl_has_changes;
/** config file name */
char* cfgfile;
};
/**
@@ -207,15 +152,6 @@ struct daemon* daemon_init(void);
*/
int daemon_open_shared_ports(struct daemon* daemon);
/**
* Do daemon setup that needs privileges
* like opening privileged ports or opening device files.
* The cfg member pointer must have been set for the daemon.
* @param daemon: the daemon.
* @return: false on error.
*/
int daemon_privileged(struct daemon* daemon);
/**
* Fork workers and start service.
* When the routine exits, it is no longer forked.
@@ -243,34 +179,4 @@ void daemon_delete(struct daemon* daemon);
*/
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
/**
* Setup acl list to have entries for the port list.
* @param list: the acl interface
* @param port_list: list of open ports, or none.
* @return false on failure
*/
int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list);
/* setups the needed ssl contexts, fatal_exit() on any failure */
void daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg);
/** See if the SSL cert files have changed */
int ssl_cert_changed(struct daemon* daemon, struct config_file* cfg);
/** Setup the listening DoT SSL_CTX, returns the ssl ctx. */
void* daemon_setup_listen_dot_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the listening DoH SSL_CTX, returns the ssl ctx. */
void* daemon_setup_listen_doh_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the listening Quic SSL_CTX, returns the ssl ctx */
void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
struct config_file* cfg);
/** Setup the connect DoT SSL_CTX, returns the ssl ctx */
void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
struct config_file* cfg);
#endif /* DAEMON_H */
+382 -5999
View File
File diff suppressed because it is too large Load Diff
+1 -170
View File
@@ -46,10 +46,8 @@
#ifndef DAEMON_REMOTE_H
#define DAEMON_REMOTE_H
#ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h>
#include "openssl/ssl.h"
#endif
#include "util/locks.h"
#include "libunbound/remote.h"
struct config_file;
struct listen_list;
struct listen_port;
@@ -57,7 +55,6 @@ struct worker;
struct comm_reply;
struct comm_point;
struct daemon_remote;
struct config_strlist_head;
/** number of milliseconds timeout on incoming remote control handshake */
#define REMOTE_CONTROL_TCP_TIMEOUT 120000
@@ -121,145 +118,6 @@ struct remote_stream {
};
typedef struct remote_stream RES;
/**
* Notification status. This is exchanged between the fast reload thread
* and the server thread, over the commpair sockets.
*/
enum fast_reload_notification {
/** nothing, not used */
fast_reload_notification_none = 0,
/** the fast reload thread is done */
fast_reload_notification_done = 1,
/** the fast reload thread is done but with an error, it failed */
fast_reload_notification_done_error = 2,
/** the fast reload thread is told to exit by the server thread.
* Sent on server quit while the reload is running. */
fast_reload_notification_exit = 3,
/** the fast reload thread has exited, after being told to exit */
fast_reload_notification_exited = 4,
/** the fast reload thread has information to print out */
fast_reload_notification_printout = 5,
/** stop as part of the reload the thread and other threads */
fast_reload_notification_reload_stop = 6,
/** ack the stop as part of the reload, and also ack start */
fast_reload_notification_reload_ack = 7,
/** resume from stop as part of the reload */
fast_reload_notification_reload_start = 8,
/** the fast reload thread wants the mainthread to poll workers,
* after the reload, sent when nopause is used */
fast_reload_notification_reload_nopause_poll = 9
};
/**
* Fast reload printout queue. Contains a list of strings, that need to be
* printed over the file descriptor.
*/
struct fast_reload_printq {
/** if this item is in a list, the previous and next */
struct fast_reload_printq *prev, *next;
/** if this item is in a list, it is true. */
int in_list;
/** list of strings to printout */
struct config_strlist_head* to_print;
/** the current item to print. It is malloced. NULL if none. */
char* client_item;
/** The length, strlen, of the client_item, that has to be sent. */
int client_len;
/** The number of bytes sent of client_item. */
int client_byte_count;
/** the comm point for the client connection, the remote control
* client. */
struct comm_point* client_cp;
/** the remote control connection to print output to. */
struct remote_stream remote;
/** the worker that the event is added in */
struct worker* worker;
};
/**
* Fast reload auth zone change. Keeps track if an auth zone was removed,
* added or changed. This is needed because workers can have events for
* dealing with auth zones, like transfers, and those have to be removed
* too, not just the auth zone structure from the tree. */
struct fast_reload_auth_change {
/** next in the list of auth zone changes. */
struct fast_reload_auth_change* next;
/** the zone in the old config */
struct auth_zone* old_z;
/** the zone in the new config */
struct auth_zone* new_z;
/** if the zone was deleted */
int is_deleted;
/** if the zone was added */
int is_added;
/** if the zone has been changed */
int is_changed;
};
/**
* Fast reload thread structure
*/
struct fast_reload_thread {
/** the thread number for the dtio thread,
* must be first to cast thread arg to int* in checklock code. */
int threadnum;
/** communication socket pair, that sends commands */
int commpair[2];
/** thread id, of the io thread */
ub_thread_type tid;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** if the thread has to quit */
int need_to_quit;
/** verbosity of the fast_reload command, the number of +v options */
int fr_verb;
/** option to not pause threads during reload */
int fr_nopause;
/** option to drop mesh queries */
int fr_drop_mesh;
/** the event that listens on the remote service worker to the
* commpair, it receives content from the fast reload thread. */
void* service_event;
/** if the event that listens on the remote service worker has
* been added to the comm base. */
int service_event_is_added;
/** the service event can read a cmd, nonblocking, so it can
* save the partial read cmd here */
uint32_t service_read_cmd;
/** the number of bytes in service_read_cmd */
int service_read_cmd_count;
/** the worker that the service_event is added in */
struct worker* worker;
/** the printout of output to the remote client. */
struct fast_reload_printq *printq;
/** lock on fr_output, to stop race when both remote control thread
* and fast reload thread use fr_output list. */
lock_basic_type fr_output_lock;
/** list of strings, that the fast reload thread produces that have
* to be printed. The remote control thread can pick them up with
* the lock. */
struct config_strlist_head* fr_output;
/** communication socket pair, to respond to the reload request */
int commreload[2];
/** the list of auth zone changes. */
struct fast_reload_auth_change* auth_zone_change_list;
/** the old tree of auth zones, to lookup. */
struct auth_zones* old_auth_zones;
/** If the ssl ctxs have changed. */
int sslctxs_changed;
};
/**
* Create new remote control state for the daemon.
* @param cfg: config file with key file settings.
@@ -345,31 +203,4 @@ int ssl_printf(RES* ssl, const char* format, ...)
int ssl_read_line(RES* ssl, char* buf, size_t max);
#endif /* HAVE_SSL */
/**
* Start fast reload thread
* @param ssl: the RES connection to print to.
* @param worker: the remote servicing worker.
* @param s: the rc_state that is servicing the remote control connection to
* the remote control client. It needs to be moved away to stay connected
* while the fast reload is running.
* @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some
* and 2 is more detail.
* @param fr_nopause: option to not pause threads during reload.
* @param fr_drop_mesh: option to drop mesh queries.
*/
void fast_reload_thread_start(RES* ssl, struct worker* worker,
struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh);
/**
* Stop fast reload thread
* @param fast_reload_thread: the thread struct.
*/
void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread);
/** fast reload printq delete list */
void fast_reload_printq_list_delete(struct fast_reload_printq* list);
/** Pick up per worker changes after a fast reload. */
void fast_reload_worker_pickup_changes(struct worker* worker);
#endif /* DAEMON_REMOTE_H */
+40 -151
View File
@@ -4,22 +4,22 @@
* Copyright (c) 2007, 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
@@ -70,9 +70,6 @@
#include <openssl/ssl.h>
#endif
/** How long to wait for threads to transmit statistics, in msec. */
#define STATS_THREAD_WAIT 60000
/** add timers and the values do not overflow or become negative */
static void
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
@@ -80,7 +77,7 @@ stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long l
#ifndef S_SPLINT_S
(*d_sec) += add_sec;
(*d_usec) += add_usec;
if((*d_usec) >= 1000000) {
if((*d_usec) > 1000000) {
(*d_usec) -= 1000000;
(*d_sec)++;
}
@@ -116,8 +113,8 @@ void server_stats_log(struct ub_server_stats* stats, struct worker* worker,
log_info("server stats for thread %d: %u queries, "
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
"ip ratelimiting",
threadnum, (unsigned)stats->num_queries,
(unsigned)(stats->num_queries -
threadnum, (unsigned)stats->num_queries,
(unsigned)(stats->num_queries -
stats->num_queries_missed_cache),
(unsigned)stats->num_queries_missed_cache,
(unsigned)stats->num_queries_prefetch,
@@ -140,7 +137,7 @@ static void
set_subnet_stats(struct worker* worker, struct ub_server_stats* svr,
int reset)
{
int m = modstack_find(&worker->env.mesh->mods, "subnetcache");
int m = modstack_find(&worker->env.mesh->mods, "subnet");
struct subnet_env* sne;
if(m == -1)
return;
@@ -262,7 +259,6 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr = worker->stats;
s->mesh_num_states = (long long)worker->env.mesh->all.count;
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs;
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
@@ -274,27 +270,14 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
/* add in the values from the mesh */
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.val_ops += (long long)worker->env.mesh->val_ops;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
for(i=0; i<UB_STATS_RCODE_NUM; i++)
for(i=0; i<16; i++)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i];
timehist_export(worker->env.mesh->histogram, s->svr.hist,
timehist_export(worker->env.mesh->histogram, s->svr.hist,
NUM_BUCKETS_HIST);
s->svr.num_queries_discard_timeout +=
(long long)worker->env.mesh->num_queries_discard_timeout;
s->svr.num_queries_replyaddr_limit +=
(long long)worker->env.mesh->num_queries_replyaddr_limit;
s->svr.num_queries_wait_limit +=
(long long)worker->env.mesh->num_queries_wait_limit;
s->svr.num_dns_error_reports +=
(long long)worker->env.mesh->num_dns_error_reports;
/* values from outside network */
s->svr.unwanted_replies = (long long)worker->back->unwanted_replies;
s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing;
s->svr.qudp_outgoing = (long long)worker->back->num_udp_outgoing;
/* get and reset validator rrset bogus number */
s->svr.rrset_bogus = (long long)get_rrset_bogus(worker, reset);
@@ -303,10 +286,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.queries_ratelimited = (long long)get_queries_ratelimit(worker, reset);
/* get cache sizes */
get_slabhash_stats(worker->env.msg_cache,
&s->svr.msg_cache_count, &s->svr.msg_cache_max_collisions);
get_slabhash_stats(&worker->env.rrset_cache->table,
&s->svr.rrset_cache_count, &s->svr.rrset_cache_max_collisions);
s->svr.msg_cache_count = (long long)count_slabhash_entries(worker->env.msg_cache);
s->svr.rrset_cache_count = (long long)count_slabhash_entries(&worker->env.rrset_cache->table);
s->svr.infra_cache_count = (long long)count_slabhash_entries(worker->env.infra_cache->hosts);
if(worker->env.key_cache)
s->svr.key_cache_count = (long long)count_slabhash_entries(worker->env.key_cache->slab);
@@ -335,21 +316,23 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.num_query_dnscrypt_replay = 0;
#endif /* USE_DNSCRYPT */
if(worker->env.auth_zones) {
s->svr.num_query_authzone_up += (long long)worker->env.mesh->num_query_authzone_up;
s->svr.num_query_authzone_down += (long long)worker->env.mesh->num_query_authzone_down;
if(reset && !worker->env.cfg->stat_cumulative) {
lock_rw_wrlock(&worker->env.auth_zones->lock);
} else {
lock_rw_rdlock(&worker->env.auth_zones->lock);
}
s->svr.num_query_authzone_up = (long long)worker->env.
auth_zones->num_query_up;
s->svr.num_query_authzone_down = (long long)worker->env.
auth_zones->num_query_down;
if(reset && !worker->env.cfg->stat_cumulative) {
worker->env.auth_zones->num_query_up = 0;
worker->env.auth_zones->num_query_down = 0;
}
lock_rw_unlock(&worker->env.auth_zones->lock);
}
s->svr.mem_stream_wait =
(long long)tcp_req_info_get_stream_buffer_size();
s->svr.mem_http2_query_buffer =
(long long)http2_get_query_buffer_size();
s->svr.mem_http2_response_buffer =
(long long)http2_get_response_buffer_size();
#ifdef HAVE_NGTCP2
s->svr.mem_quic = (long long)doq_table_quic_size_get(
worker->daemon->doq_table);
#else
s->svr.mem_quic = 0;
#endif /* HAVE_NGTCP2 */
/* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset);
@@ -360,11 +343,6 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.num_query_subnet = 0;
s->svr.num_query_subnet_cache = 0;
#endif
#ifdef USE_CACHEDB
s->svr.num_query_cachedb = (long long)worker->env.mesh->ans_cachedb;
#else
s->svr.num_query_cachedb = 0;
#endif
/* get tcp accept usage */
s->svr.tcp_accept_usage = 0;
@@ -394,56 +372,11 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
worker_send_cmd(who, worker_cmd_stats);
else worker_send_cmd(who, worker_cmd_stats_noreset);
verbose(VERB_ALGO, "wait for stats reply");
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
unsigned long pthid = 0;
if(verbosity >= VERB_OPS)
memcpy(&pthid, &who->thr_id, sizeof(unsigned long));
# endif
#endif
verbose(VERB_OPS, "no response from thread %d"
#ifdef HAVE_GETTID
" LWP %u"
#endif
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
" pthread 0x%lx"
# endif
#endif
,
who->thread_num
#ifdef HAVE_GETTID
, (unsigned)who->thread_tid
#endif
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
, pthid
# endif
#endif
);
log_err("server_stats_obtain: no response from worker %d "
"(stats timeout); returning zero stats for this worker",
who->thread_num);
/* A later reply from the worker, would be sizeof stats reply,
* and the worker_handle_control_cmd routine discards if
* it is not a 4byte command, when that is received here. */
memset(s, 0, sizeof(*s));
return;
}
if(!tube_read_msg(worker->cmd, &reply, &len, 0)) {
log_err("server_stats_obtain: failed to read stats from worker "
"(tube read error); returning zero stats for this worker");
memset(s, 0, sizeof(*s));
return;
}
if(len != (uint32_t)sizeof(*s)) {
log_err("server_stats_obtain: wrong stats length %d (expected %d); "
"discarding", (int)len, (int)sizeof(*s));
free(reply);
memset(s, 0, sizeof(*s));
return;
}
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
fatal_exit("failed to read stats over cmd channel");
if(len != (uint32_t)sizeof(*s))
fatal_exit("stats on cmd channel wrong length %d %d",
(int)len, (int)sizeof(*s));
memcpy(s, reply, (size_t)len);
free(reply);
}
@@ -453,39 +386,24 @@ void server_stats_reply(struct worker* worker, int reset)
struct ub_stats_info s;
server_stats_compile(worker, &s, reset);
verbose(VERB_ALGO, "write stats replymsg");
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
(uint8_t*)&s, sizeof(s), 0))
log_err("could not write stat values over cmd channel");
fatal_exit("could not write stat values over cmd channel");
}
void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
{
total->svr.num_queries += a->svr.num_queries;
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
total->svr.num_queries_cookie_valid += a->svr.num_queries_cookie_valid;
total->svr.num_queries_cookie_client += a->svr.num_queries_cookie_client;
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
total->svr.num_queries_discard_timeout +=
a->svr.num_queries_discard_timeout;
total->svr.num_queries_replyaddr_limit +=
a->svr.num_queries_replyaddr_limit;
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
total->svr.num_queries_timed_out += a->svr.num_queries_timed_out;
total->svr.num_query_authzone_up += a->svr.num_query_authzone_up;
total->svr.num_query_authzone_down += a->svr.num_query_authzone_down;
if (total->svr.max_query_time_us < a->svr.max_query_time_us)
total->svr.max_query_time_us = a->svr.max_query_time_us;
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
total->svr.ans_expired += a->svr.ans_expired;
#ifdef USE_DNSCRYPT
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
total->svr.num_query_dnscrypt_cleartext +=
total->svr.num_query_dnscrypt_cleartext += \
a->svr.num_query_dnscrypt_cleartext;
total->svr.num_query_dnscrypt_crypted_malformed +=
total->svr.num_query_dnscrypt_crypted_malformed += \
a->svr.num_query_dnscrypt_crypted_malformed;
#endif /* USE_DNSCRYPT */
/* the max size reached is upped to higher of both */
@@ -498,11 +416,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qclass_big += a->svr.qclass_big;
total->svr.qtcp += a->svr.qtcp;
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
total->svr.qudp_outgoing += a->svr.qudp_outgoing;
total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qhttps += a->svr.qhttps;
total->svr.qquic += a->svr.qquic;
total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA;
@@ -515,15 +430,12 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qEDNS += a->svr.qEDNS;
total->svr.qEDNS_DO += a->svr.qEDNS_DO;
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
total->svr.ans_secure += a->svr.ans_secure;
total->svr.ans_bogus += a->svr.ans_bogus;
total->svr.val_ops += a->svr.val_ops;
total->svr.unwanted_replies += a->svr.unwanted_replies;
total->svr.unwanted_queries += a->svr.unwanted_queries;
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
#ifdef USE_CACHEDB
total->svr.num_query_cachedb += a->svr.num_query_cachedb;
#endif
for(i=0; i<UB_STATS_QTYPE_NUM; i++)
total->svr.qtype[i] += a->svr.qtype[i];
for(i=0; i<UB_STATS_QCLASS_NUM; i++)
@@ -534,13 +446,10 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.ans_rcode[i] += a->svr.ans_rcode[i];
for(i=0; i<NUM_BUCKETS_HIST; i++)
total->svr.hist[i] += a->svr.hist[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
total->svr.rpz_action[i] += a->svr.rpz_action[i];
}
total->mesh_num_states += a->mesh_num_states;
total->mesh_num_reply_states += a->mesh_num_reply_states;
total->mesh_num_reply_addrs += a->mesh_num_reply_addrs;
total->mesh_jostled += a->mesh_jostled;
total->mesh_dropped += a->mesh_dropped;
total->mesh_replies_sent += a->mesh_replies_sent;
@@ -564,23 +473,16 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
else stats->qclass_big++;
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
if(c->type != comm_udp) {
if(c->type != comm_doq)
stats->qtcp++;
stats->qtcp++;
if(c->ssl != NULL) {
stats->qtls++;
#ifdef HAVE_SSL
if(SSL_session_reused(c->ssl))
if(SSL_session_reused(c->ssl))
stats->qtls_resume++;
#endif
if(c->type == comm_http)
stats->qhttps++;
#ifdef HAVE_NGTCP2
else if(c->type == comm_doq)
stats->qquic++;
#endif
}
}
if(repinfo && addr_is_ip6(&repinfo->remote_addr, repinfo->remote_addrlen))
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
stats->qipv6++;
if( (flags&BIT_QR) )
stats->qbit_QR++;
@@ -614,16 +516,3 @@ void server_stats_insrcode(struct ub_server_stats* stats, sldns_buffer* buf)
stats->ans_rcode_nodata ++;
}
}
void server_stats_downstream_cookie(struct ub_server_stats* stats,
struct edns_data* edns)
{
if(!(edns->edns_present && edns->cookie_present)) return;
if(edns->cookie_valid) {
stats->num_queries_cookie_valid++;
} else if(edns->cookie_client) {
stats->num_queries_cookie_client++;
} else {
stats->num_queries_cookie_invalid++;
}
}
-7
View File
@@ -126,11 +126,4 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
*/
void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* buf);
/**
* Add DNS Cookie stats for this query
* @param stats: the stats
* @param edns: edns record
*/
void server_stats_downstream_cookie(struct ub_server_stats* stats,
struct edns_data* edns);
#endif /* DAEMON_STATS_H */
+87 -149
View File
@@ -88,28 +88,31 @@
# include "nss.h"
#endif
#ifdef HAVE_TARGETCONDITIONALS_H
#include <TargetConditionals.h>
#endif
#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
#undef HAVE_FORK
#endif
/** print build options. */
static void
print_build_options(void)
/** print usage. */
static void usage(void)
{
const char** m;
const char *evnm="event", *evsys="", *evmethod="";
time_t t;
struct timeval now;
struct ub_event_base* base;
printf("Version %s\n\n", PACKAGE_VERSION);
printf("Configure line: %s\n", CONFCMDLINE);
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help\n");
printf("-c file config file to read instead of %s\n", CONFIGFILE);
printf(" file format is described in unbound.conf(5).\n");
printf("-d do not fork into the background.\n");
printf("-p do not create a pidfile.\n");
printf("-v verbose (more times to increase verbosity)\n");
#ifdef UB_ON_WINDOWS
printf("-w opt windows option: \n");
printf(" install, remove - manage the services entry\n");
printf(" service - used to start from services control panel\n");
#endif
printf("Version %s\n", PACKAGE_VERSION);
base = ub_default_event_base(0,&t,&now);
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
printf("Linked libs: %s %s (it uses %s), %s\n",
printf("linked libs: %s %s (it uses %s), %s\n",
evnm, evsys, evmethod,
#ifdef HAVE_SSL
# ifdef SSLEAY_VERSION
@@ -123,42 +126,16 @@ print_build_options(void)
"nettle"
#endif
);
printf("Linked modules:");
printf("linked modules:");
for(m = module_list_avail(); *m; m++)
printf(" %s", *m);
printf("\n");
#ifdef USE_DNSCRYPT
printf("DNSCrypt feature available\n");
#endif
#ifdef USE_TCP_FASTOPEN
printf("TCP Fastopen feature available\n");
#endif
ub_event_base_free(base);
printf("\nBSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
}
/** print usage. */
static void
usage(void)
{
printf("usage: unbound [options]\n");
printf(" start unbound daemon DNS resolver.\n");
printf("-h this help.\n");
printf("-c file config file to read instead of %s\n", CONFIGFILE);
printf(" file format is described in unbound.conf(5).\n");
printf("-d do not fork into the background.\n");
printf("-p do not create a pidfile.\n");
printf("-v verbose (more times to increase verbosity).\n");
printf("-V show version number and build options.\n");
#ifdef UB_ON_WINDOWS
printf("-w opt windows option: \n");
printf(" install, remove - manage the services entry\n");
printf(" service - used to start from services control panel\n");
#endif
printf("\nVersion %s\n", PACKAGE_VERSION);
printf("BSD licensed, see LICENSE in source package for details.\n");
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
ub_event_base_free(base);
}
#ifndef unbound_testbound
@@ -174,7 +151,7 @@ static void
checkrlimits(struct config_file* cfg)
{
#ifndef S_SPLINT_S
#if defined(HAVE_GETRLIMIT) && !defined(unbound_testbound)
#ifdef HAVE_GETRLIMIT
/* list has number of ports to listen to, ifs number addresses */
int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 +
(int)cfg->incoming_num_tcp:0));
@@ -197,35 +174,6 @@ checkrlimits(struct config_file* cfg)
size_t total = numthread * perthread + misc;
size_t avail;
struct rlimit rlim;
size_t memsize_expect = cfg->msg_cache_size + cfg->rrset_cache_size
+ (cfg->do_tcp?cfg->stream_wait_size:0)
+ (cfg->ip_ratelimit?cfg->ip_ratelimit_size:0)
+ (cfg->ratelimit?cfg->ratelimit_size:0)
+ (cfg->dnscrypt?cfg->dnscrypt_shared_secret_cache_size + cfg->dnscrypt_nonce_cache_size:0)
+ cfg->infra_cache_numhosts * (sizeof(struct infra_key)+sizeof(struct infra_data));
if(strstr(cfg->module_conf, "validator") && (cfg->trust_anchor_file_list || cfg->trust_anchor_list || cfg->auto_trust_anchor_file_list || cfg->trusted_keys_file_list)) {
memsize_expect += cfg->key_cache_size + cfg->neg_cache_size;
}
#ifdef HAVE_NGHTTP2_NGHTTP2_H
if(cfg_has_https(cfg)) {
memsize_expect += cfg->http_query_buffer_size + cfg->http_response_buffer_size;
}
#endif
#ifdef RLIMIT_AS
if(getrlimit(RLIMIT_AS, &rlim) == 0) {
if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
rlim.rlim_cur < (rlim_t)memsize_expect) {
log_warn("the ulimit(max memory size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
}
}
#endif
if(getrlimit(RLIMIT_DATA, &rlim) == 0) {
if(rlim.rlim_cur != (rlim_t)RLIM_INFINITY &&
rlim.rlim_cur < (rlim_t)memsize_expect) {
log_warn("the ulimit(data seg size) is smaller than the expected memory usage (added size of caches). %u < %u bytes", (unsigned)rlim.rlim_cur, (unsigned)memsize_expect);
}
}
if(total > 1024 &&
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
@@ -296,10 +244,21 @@ checkrlimits(struct config_file* cfg)
#endif /* S_SPLINT_S */
}
/** set default logfile identity based on value from argv[0] at startup **/
static void
log_ident_set_fromdefault(struct config_file* cfg,
const char *log_default_identity)
{
if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
log_ident_set(log_default_identity);
else
log_ident_set(cfg->log_identity);
}
/** set verbosity, check rlimits, cache settings */
static void
apply_settings(struct daemon* daemon, struct config_file* cfg,
int cmdline_verbose, int debug_mode)
apply_settings(struct daemon* daemon, struct config_file* cfg,
int cmdline_verbose, int debug_mode, const char* log_default_identity)
{
/* apply if they have changed */
verbosity = cmdline_verbose + cfg->verbosity;
@@ -315,7 +274,7 @@ apply_settings(struct daemon* daemon, struct config_file* cfg,
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
}
log_ident_set_or_default(cfg->log_identity);
log_ident_set_fromdefault(cfg, log_default_identity);
}
#ifdef HAVE_KILL
@@ -370,38 +329,18 @@ readpid (const char* file)
static void
writepid (const char* pidfile, pid_t pid)
{
int fd;
char pidbuf[32];
size_t count = 0;
snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid);
FILE* f;
if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC
#ifdef O_NOFOLLOW
| O_NOFOLLOW
#endif
, 0644)) == -1) {
if ((f = fopen(pidfile, "w")) == NULL ) {
log_err("cannot open pidfile %s: %s",
pidfile, strerror(errno));
return;
}
while(count < strlen(pidbuf)) {
ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
if(r == -1) {
if(errno == EAGAIN || errno == EINTR)
continue;
log_err("cannot write to pidfile %s: %s",
pidfile, strerror(errno));
close(fd);
return;
} else if(r == 0) {
log_err("cannot write any bytes to pidfile %s: "
"write returns 0 bytes written", pidfile);
close(fd);
return;
}
count += r;
if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) {
log_err("cannot write to pidfile %s: %s",
pidfile, strerror(errno));
}
close(fd);
fclose(f);
}
/**
@@ -463,18 +402,6 @@ detach(void)
#endif /* HAVE_DAEMON */
}
/** setup the remote and ticket keys */
static void
setup_sslctx_remote(struct daemon* daemon, struct config_file* cfg)
{
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
fatal_exit("could not set up remote-control");
#else /* HAVE_SSL */
(void)daemon;(void)cfg;
#endif /* HAVE_SSL */
}
/** daemonize, drop user privileges and chroot if needed */
static void
perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
@@ -485,11 +412,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#endif
#ifdef HAVE_GETPWNAM
struct passwd *pwd = NULL;
#endif
if(!daemon_privileged(daemon))
fatal_exit("could not do privileged setup");
#ifdef HAVE_GETPWNAM
if(cfg->username && cfg->username[0]) {
if((pwd = getpwnam(cfg->username)) == NULL)
fatal_exit("user '%s' does not exist.", cfg->username);
@@ -501,8 +424,35 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#endif
/* read ssl keys while superuser and outside chroot */
setup_sslctx_remote(daemon, cfg);
daemon_setup_sslctxs(daemon, cfg);
#ifdef HAVE_SSL
if(!(daemon->rc = daemon_remote_create(cfg)))
fatal_exit("could not set up remote-control");
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
if(!(daemon->listen_sslctx = listen_sslctx_create(
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
fatal_exit("could not set up listen SSL_CTX");
if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
}
}
#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
}
}
#endif
if(cfg->tls_session_ticket_keys.first) {
if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
fatal_exit("could not set session ticket SSL_CTX");
}
}
}
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
cfg->tls_cert_bundle, cfg->tls_win_cert)))
fatal_exit("could not set up connect SSL_CTX");
#endif
/* init syslog (as root) if needed, before daemonize, otherwise
* a fork error could not be printed since daemonize closed stderr.*/
@@ -531,15 +481,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
cfg, 1);
if(!daemon->pidfile)
fatal_exit("pidfile alloc: out of memory");
/* Check old pid if there is no username configured.
* With a username, the assumption is that the privilege
* drop makes a pidfile not removed when the server stopped
* last time. The server does not chown the pidfile for it,
* because that creates privilege escape problems, with the
* pidfile writable by unprivileged users, but used by
* privileged users. */
if(!(cfg->username && cfg->username[0]))
checkoldpid(daemon->pidfile, pidinchroot);
checkoldpid(daemon->pidfile, pidinchroot);
}
#endif
@@ -552,6 +494,16 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
#ifdef HAVE_KILL
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
writepid(daemon->pidfile, getpid());
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
pidinchroot) {
# ifdef HAVE_CHOWN
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
(unsigned)cfg_uid, (unsigned)cfg_gid,
daemon->pidfile, strerror(errno));
}
# endif /* HAVE_CHOWN */
}
}
#else
(void)daemon;
@@ -569,8 +521,6 @@ 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 */
@@ -665,9 +615,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
* it would succeed on SIGHUP as well */
if(!cfg->use_syslog)
log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir);
daemon->cfgfile = strdup(*cfgfile);
if(!daemon->cfgfile)
fatal_exit("out of memory in daemon cfgfile strdup");
}
/**
@@ -676,10 +623,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
* @param cmdline_verbose: verbosity resulting from commandline -v.
* These increase verbosity as specified in the config file.
* @param debug_mode: if set, do not daemonize.
* @param log_default_identity: Default identity to report in logs
* @param need_pidfile: if false, no pidfile is checked or created.
*/
static void
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pidfile)
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity, int need_pidfile)
{
struct config_file* cfg = NULL;
struct daemon* daemon = NULL;
@@ -702,9 +650,8 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
"the commandline to see more errors, "
"or unbound-checkconf", cfgfile);
log_warn("Continuing with default config settings");
config_auto_slab_values(cfg);
}
apply_settings(daemon, cfg, cmdline_verbose, debug_mode);
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
if(!done_setup)
config_lookup_uid(cfg);
@@ -733,11 +680,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, int need_pi
if(daemon->pidfile) {
int fd;
/* truncate pidfile */
fd = open(daemon->pidfile, O_WRONLY | O_TRUNC
#ifdef O_NOFOLLOW
| O_NOFOLLOW
#endif
, 0644);
fd = open(daemon->pidfile, O_WRONLY | O_TRUNC, 0644);
if(fd != -1)
close(fd);
/* delete pidfile */
@@ -772,13 +715,11 @@ main(int argc, char* argv[])
int cmdline_cfg = 0;
#endif
checklock_start();
log_init(NULL, 0, NULL);
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
log_ident_set_default(log_ident_default);
log_ident_set(log_ident_default);
/* parse the options */
while( (c=getopt(argc, argv, "c:dhpvw:V")) != -1) {
while( (c=getopt(argc, argv, "c:dhpvw:")) != -1) {
switch(c) {
case 'c':
cfgfile = optarg;
@@ -799,9 +740,6 @@ main(int argc, char* argv[])
case 'w':
winopt = optarg;
break;
case 'V':
print_build_options();
return 0;
case '?':
case 'h':
default:
@@ -826,11 +764,11 @@ main(int argc, char* argv[])
return 1;
}
run_daemon(cfgfile, cmdline_verbose, debug_mode, need_pidfile);
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default, need_pidfile);
log_init(NULL, 0, NULL); /* close logfile */
#ifndef unbound_testbound
if(log_get_lock()) {
lock_basic_destroy((lock_basic_type*)log_get_lock());
lock_quick_destroy((lock_quick_type*)log_get_lock());
}
#endif
return 0;
+469 -1126
View File
File diff suppressed because it is too large Load Diff
+9 -15
View File
@@ -72,13 +72,7 @@ enum worker_commands {
/** obtain statistics without statsclear */
worker_cmd_stats_noreset,
/** execute remote control command */
worker_cmd_remote,
/** for fast-reload, perform stop */
worker_cmd_reload_stop,
/** for fast-reload, start again */
worker_cmd_reload_start,
/** for fast-reload, poll to make sure worker has released data */
worker_cmd_reload_poll
worker_cmd_remote
};
/**
@@ -92,10 +86,6 @@ struct worker {
struct daemon* daemon;
/** thread id */
ub_thread_type thr_id;
#ifdef HAVE_GETTID
/** thread tid, the LWP id. */
pid_t thread_tid;
#endif
/** pipe, for commands for this worker */
struct tube* cmd;
/** the event base this worker works with */
@@ -104,6 +94,10 @@ struct worker {
struct listen_dnsport* front;
/** the backside outside network interface to the auth servers */
struct outside_network* back;
/** ports to be used by this worker. */
int* ports;
/** number of ports for this worker */
int numports;
/** the signal handler */
struct comm_signal* comsig;
/** commpoint to listen to commands. */
@@ -120,7 +114,7 @@ struct worker {
/** do we need to restart or quit (on signal) */
int need_to_exit;
/** allocation cache for this thread */
struct alloc_cache *alloc;
struct alloc_cache alloc;
/** per thread statistics */
struct ub_server_stats stats;
/** thread scratch regional */
@@ -133,8 +127,6 @@ struct worker {
/** dnstap environment, changed for this thread */
struct dt_env dtenv;
#endif
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
};
/**
@@ -142,9 +134,11 @@ struct worker {
* with backpointers only. Use worker_init on it later.
* @param daemon: the daemon that this worker thread is part of.
* @param id: the thread number from 0.. numthreads-1.
* @param ports: the ports it is allowed to use, array.
* @param n: the number of ports.
* @return: the new worker or NULL on alloc failure.
*/
struct worker* worker_create(struct daemon* daemon, int id);
struct worker* worker_create(struct daemon* daemon, int id, int* ports, int n);
/**
* Initialize worker.
+93 -199
View File
@@ -59,7 +59,7 @@
******************************************************************************/
/**
* This is the default DNS64 prefix that is used when the dns64 module is listed
* This is the default DNS64 prefix that is used whent he dns64 module is listed
* in module-config but when the dns64-prefix variable is not present.
*/
static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
@@ -191,24 +191,18 @@ uitoa(unsigned n, char* s)
*
* \param ipv6 IPv6 address represented as a 128-bit array in big-endian
* order.
* \param ipv6_len length of the ipv6 byte array.
* \param offset Index of the MSB of the IPv4 address embedded in the IPv6
* address.
*/
static uint32_t
extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
extract_ipv4(const uint8_t ipv6[16], const int offset)
{
uint32_t ipv4 = 0;
int i, pos;
log_assert(ipv6_len == 16); (void)ipv6_len;
log_assert(offset == 32 || offset == 40 || offset == 48 || offset == 56 ||
offset == 64 || offset == 96);
for(i = 0, pos = offset / 8; i < 4; i++, pos++) {
if (pos == 8)
pos++;
ipv4 = ipv4 << 8;
ipv4 |= ipv6[pos];
}
uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
if (offset/8+4 < 16)
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
return ipv4;
}
@@ -220,26 +214,22 @@ extract_ipv4(const uint8_t ipv6[], size_t ipv6_len, const int offset)
* \param ipv4 IPv4 address represented as an unsigned 32-bit number.
* \param ptr The result will be written here. Must be large enough, be
* careful!
* \param nm_len length of the ptr buffer.
*
* \return The number of characters written.
*/
static size_t
ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
{
static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
int i;
char* c = ptr;
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);
c += *c + 1;
log_assert(c < ptr+nm_len);
ipv4 /= 256;
}
log_assert(c + sizeof(IPV4_PTR_SUFFIX) <= ptr+nm_len);
memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX));
return c + sizeof(IPV4_PTR_SUFFIX) - ptr;
@@ -251,15 +241,13 @@ ipv4_to_ptr(uint32_t ipv4, char ptr[], size_t nm_len)
*
* \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
* \param ipv6 The result will be written here, in network byte order.
* \param ipv6_len length of the ipv6 byte array.
*
* \return 1 on success, 0 on failure.
*/
static int
ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len)
ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
{
int i;
log_assert(ipv6_len == 16); (void)ipv6_len;
for (i = 0; i < 64; i++) {
int x;
@@ -287,30 +275,24 @@ ptr_to_ipv6(const char* ptr, uint8_t ipv6[], size_t ipv6_len)
* Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
*
* \param prefix_addr DNS64 prefix address.
* \param prefix_addr_len length of the prefix_addr buffer.
* \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96.
* \param a IPv4 address.
* \param a_len length of the a buffer.
* \param aaaa IPv6 address. The result will be written here.
* \param aaaa_len length of the aaaa buffer.
*/
static void
synthesize_aaaa(const uint8_t prefix_addr[], size_t prefix_addr_len,
int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[],
size_t aaaa_len)
synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
const uint8_t a[4], uint8_t aaaa[16])
{
size_t i;
int pos;
log_assert(prefix_addr_len == 16 && a_len == 4 && aaaa_len == 16);
log_assert(prefix_net == 32 || prefix_net == 40 || prefix_net == 48 ||
prefix_net == 56 || prefix_net == 64 || prefix_net == 96);
(void)prefix_addr_len; (void)a_len; (void)aaaa_len;
memcpy(aaaa, prefix_addr, 16);
for(i = 0, pos = prefix_net / 8; i < a_len; i++, pos++) {
if(pos == 8)
aaaa[pos++] = 0;
aaaa[pos] = a[i];
}
aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
aaaa[prefix_net/8+1] |= a[1] >> (0+prefix_net%8);
aaaa[prefix_net/8+2] |= a[1] << (8-prefix_net%8);
aaaa[prefix_net/8+2] |= a[2] >> (0+prefix_net%8);
aaaa[prefix_net/8+3] |= a[2] << (8-prefix_net%8);
aaaa[prefix_net/8+3] |= a[3] >> (0+prefix_net%8);
if (prefix_net/8+4 < 16) /* <-- my beautiful symmetry is destroyed! */
aaaa[prefix_net/8+4] |= a[3] << (8-prefix_net%8);
}
@@ -366,23 +348,20 @@ static int
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
{
struct config_strlist* s;
const char* dns64_prefix = cfg->dns64_prefix ?
cfg->dns64_prefix : DEFAULT_DNS64_PREFIX;
verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix);
if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr,
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix);
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
return 0;
}
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
log_err("dns64_prefix is not IPv6: %s", dns64_prefix);
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
return 0;
}
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s",
dns64_prefix);
if (dns64_env->prefix_net < 0 || dns64_env->prefix_net > 96) {
log_err("dns64-prefix length it not between 0 and 96: %s",
cfg->dns64_prefix);
return 0;
}
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
@@ -468,8 +447,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
/* Convert the PTR query string to an IPv6 address. */
memset(&sin6, 0, sizeof(sin6));
sin6.sin6_family = AF_INET6;
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr,
sizeof(sin6.sin6_addr.s6_addr)))
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
return module_wait_module; /* Let other module handle this. */
/*
@@ -492,13 +470,12 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id)
if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
return module_error;
qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
sizeof(sin6.sin6_addr.s6_addr), dns64_env->prefix_net),
(char*)qinfo.qname, MAX_PTR_QNAME_IPV4);
dns64_env->prefix_net), (char*)qinfo.qname);
/* Create the new sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
&subq))
return module_error;
if (subq) {
subq->curmod = id;
@@ -523,8 +500,8 @@ generate_type_A_query(struct module_qstate* qstate, int id)
/* Start the sub-query. */
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info,
qstate->query_flags, 0, 0, &subq))
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
0, &subq))
{
verbose(VERB_ALGO, "dns64: sub-query creation failed");
return module_error;
@@ -574,29 +551,28 @@ static enum module_ext_state
handle_event_pass(struct module_qstate* qstate, int id)
{
struct dns64_qstate* iq = (struct dns64_qstate*)qstate->minfo[id];
int synth_all_cfg = qstate->env->cfg->dns64_synthall;
int synth_qname = 0;
if (iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
&& qstate->qinfo.qname_len == 74
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
/* Handle PTR queries for IPv6 addresses. */
return handle_ipv6_ptr(qstate, id);
if(iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
&& qstate->qinfo.qname_len == 74
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa")) {
/* Handle PTR queries for IPv6 addresses. */
return handle_ipv6_ptr(qstate, id);
}
if (qstate->env->cfg->dns64_synthall &&
iq && iq->state == DNS64_NEW_QUERY
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
return generate_type_A_query(qstate, id);
if(iq && iq->state == DNS64_NEW_QUERY &&
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
(synth_all_cfg ||
(synth_qname=(dns64_always_synth_for_qname(qstate, id)
&& !(qstate->query_flags & BIT_CD))))) {
if(synth_qname)
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
if(dns64_always_synth_for_qname(qstate, id) &&
iq && iq->state == DNS64_NEW_QUERY
&& !(qstate->query_flags & BIT_CD)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
return generate_type_A_query(qstate, id);
}
/* We are finished when our sub-query is finished. */
if(iq && iq->state == DNS64_SUBQUERY_FINISHED)
if (iq && iq->state == DNS64_SUBQUERY_FINISHED)
return module_finished;
/* Otherwise, pass request to next module. */
@@ -629,47 +605,32 @@ handle_event_moddone(struct module_qstate* qstate, int id)
* synthesize in (sec 5.1.2 of RFC6147).
* - A successful AAAA query with an answer.
*/
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
&& !(qstate->query_flags & BIT_CD)
&& !(qstate->return_msg &&
qstate->return_msg->rep &&
reply_find_answer_rrset(&qstate->qinfo,
qstate->return_msg->rep)))
/* not internal, type AAAA, not CD, and no answer RRset,
* So, this is a AAAA noerror/nodata answer */
return generate_type_A_query(qstate, id);
/* When an AAAA query completes check if we want to perform DNS64
* synthesis. We skip queries with DNSSEC enabled (!CD) and
* ones generated by us to retrieve the A/PTR record to use for
* synth. */
int could_synth =
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA &&
(!iq || iq->state != DNS64_INTERNAL_QUERY) &&
!(qstate->query_flags & BIT_CD);
int has_data = /* whether query returned non-empty rrset */
qstate->return_msg &&
qstate->return_msg->rep &&
reply_find_answer_rrset(&qstate->qinfo, qstate->return_msg->rep);
int synth_qname = 0;
if(could_synth && !has_data && qstate->env->need_to_validate &&
qstate->return_msg && qstate->return_msg->rep &&
qstate->return_msg->rep->security == sec_status_bogus) {
verbose(VERB_ALGO, "dns64: bogus AAAA reply not synthesized");
could_synth = 0;
}
if(could_synth &&
(!has_data ||
(synth_qname=dns64_always_synth_for_qname(qstate, id)))) {
if(synth_qname)
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
if((!iq || iq->state != DNS64_INTERNAL_QUERY)
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA
&& !(qstate->query_flags & BIT_CD)
&& dns64_always_synth_for_qname(qstate, id)) {
/* if it is not internal, AAAA, not CD and listed domain,
* generate from A record and ignore AAAA */
verbose(VERB_ALGO, "dns64: ignore-aaaa and synthesize anyway");
return generate_type_A_query(qstate, id);
}
/* Store the response in cache. */
if( (!iq || !iq->started_no_cache_store) &&
!qstate->rpz_applied && !qstate->rpz_passthru &&
!qstate->is_subnet_answer &&
qstate->return_msg &&
qstate->return_msg->rep &&
!qstate->fwd_stub_no_cache &&
!dns_cache_store(
qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, qstate->prefetch_leeway, 0, NULL,
qstate->query_flags, qstate->qstarttime,
qstate->is_valrec))
if ( (!iq || !iq->started_no_cache_store) &&
qstate->return_msg && qstate->return_msg->rep &&
!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
0, 0, 0, NULL, qstate->query_flags))
log_err("out of memory");
/* do nothing */
@@ -702,17 +663,12 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
switch(event) {
case module_event_new:
/* Tag this query as being new and fall through. */
if (!(iq = (struct dns64_qstate*)regional_alloc(
qstate->region, sizeof(*iq)))) {
log_err("out of memory");
qstate->ext_state[id] = module_error;
return;
}
iq = (struct dns64_qstate*)regional_alloc(
qstate->region, sizeof(*iq));
qstate->minfo[id] = iq;
iq->state = DNS64_NEW_QUERY;
iq->started_no_cache_store = qstate->no_cache_store;
qstate->no_cache_store = 1;
ATTR_FALLTHROUGH
/* fallthrough */
case module_event_pass:
qstate->ext_state[id] = handle_event_pass(qstate, id);
@@ -726,15 +682,8 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
}
if(qstate->ext_state[id] == module_finished) {
iq = (struct dns64_qstate*)qstate->minfo[id];
if(iq && iq->state != DNS64_INTERNAL_QUERY) {
if(qstate->fwd_stub_no_cache) {
/* If the forward/stub has no cache, then
* continue with the query with no cache. */
qstate->no_cache_store = qstate->fwd_stub_no_cache;
} else {
qstate->no_cache_store = iq->started_no_cache_store;
}
}
if(iq && iq->state != DNS64_INTERNAL_QUERY)
qstate->no_cache_store = iq->started_no_cache_store;
}
}
@@ -756,7 +705,7 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
*dd_out = NULL;
return; /* integer overflow protection in alloc */
}
if (!(dd = *dd_out = regional_alloc_zero(region,
if (!(dd = *dd_out = regional_alloc(region,
sizeof(struct packed_rrset_data)
+ fd->count * (sizeof(size_t) + sizeof(time_t) +
sizeof(uint8_t*) + 2 + 16)))) {
@@ -791,10 +740,8 @@ dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
dd->rr_data[i][1] = 16;
synthesize_aaaa(
((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
sizeof(((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr),
dns64_env->prefix_net, &fd->rr_data[i][2],
fd->rr_len[i]-2, &dd->rr_data[i][2],
dd->rr_len[i]-2);
&dd->rr_data[i][2] );
dd->rr_ttl[i] = fd->rr_ttl[i];
}
@@ -841,7 +788,6 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
size_t i, s;
struct packed_rrset_data* fd, *dd;
struct ub_packed_rrset_key* fk, *dk;
int allocated_return_msg = 0;
verbose(VERB_ALGO, "converting A answers to AAAA answers");
@@ -857,7 +803,6 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
return;
memset(super->return_msg, 0, sizeof(*super->return_msg));
super->return_msg->qinfo = super->qinfo;
allocated_return_msg = 1;
}
rep = qstate->return_msg->rep;
@@ -867,17 +812,13 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
*/
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
rep->ttl, rep->prefetch_ttl, rep->serve_expired_ttl,
rep->serve_expired_norec_ttl,
rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets,
rep->rrset_count, rep->security, LDNS_EDE_NONE);
if(!cp) {
if(allocated_return_msg) super->return_msg = NULL;
rep->rrset_count, rep->security);
if(!cp)
return;
}
/* allocate ub_key structures special or not */
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
if(allocated_return_msg) super->return_msg = NULL;
return;
}
@@ -892,10 +833,8 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
if(i<rep->an_numrrsets && fk->rk.type == htons(LDNS_RR_TYPE_A)) {
/* also sets dk->entry.hash */
dns64_synth_aaaa_data(fk, fd, dk, &dd, super->region, dns64_env);
if(!dd) {
if(allocated_return_msg) super->return_msg = NULL;
if(!dd)
return;
}
/* Delete negative AAAA record from cache stored by
* the iterator module */
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
@@ -912,19 +851,15 @@ dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
fk->rk.dname, fk->rk.dname_len);
if(!dk->rk.dname) {
if(allocated_return_msg) super->return_msg = NULL;
if(!dk->rk.dname)
return;
}
s = packed_rrset_sizeof(fd);
dd = (struct packed_rrset_data*)regional_alloc_init(
super->region, fd, s);
if(!dd) {
if(allocated_return_msg) super->return_msg = NULL;
if(!dd)
return;
}
}
packed_rrset_ptr_fixup(dd);
@@ -954,11 +889,8 @@ dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
sizeof(struct dns_msg))))
return;
super->return_msg->qinfo = super->qinfo;
if (!(super->return_msg->rep = reply_info_copy(qstate->return_msg->rep,
NULL, super->region))) {
super->return_msg = NULL;
return;
}
super->return_msg->rep = reply_info_copy(qstate->return_msg->rep, NULL,
super->region);
/*
* Adjust the domain name of the answer RR set so that it matches the
@@ -996,52 +928,22 @@ dns64_inform_super(struct module_qstate* qstate, int id,
if(!super_dq) {
super_dq = (struct dns64_qstate*)regional_alloc(super->region,
sizeof(*super_dq));
if(!super_dq) {
log_err("out of memory");
super->return_rcode = LDNS_RCODE_SERVFAIL;
super->return_msg = NULL;
return;
}
super->minfo[id] = super_dq;
memset(super_dq, 0, sizeof(*super_dq));
super_dq->started_no_cache_store = super->no_cache_store;
}
super_dq->state = DNS64_SUBQUERY_FINISHED;
/* If there is no successful answer, we're done.
* Guarantee that we have at least a NOERROR reply further on. */
if(qstate->return_rcode != LDNS_RCODE_NOERROR
|| !qstate->return_msg
|| !qstate->return_msg->rep) {
return;
}
/* When no A record is found for synthesis fall back to AAAA again. */
if(qstate->qinfo.qtype == LDNS_RR_TYPE_A &&
!reply_find_answer_rrset(&qstate->qinfo,
qstate->return_msg->rep)) {
super_dq->state = DNS64_INTERNAL_QUERY;
/* If there is no successful answer, we're done. */
if (qstate->return_rcode != LDNS_RCODE_NOERROR
|| !qstate->return_msg
|| !qstate->return_msg->rep) {
return;
}
/* Use return code from A query in response to client. */
if (super->return_rcode != LDNS_RCODE_NOERROR)
super->return_rcode = qstate->return_rcode;
/* RPZ applied to the subquery need to then change (not cache)
* the super query. With the super query not cached, it is
* going to run the state machine modules on incoming queries,
* that fetch the subquery (cache) response, and modify it
* according to the rpz policy. That makes the synthesized
* super query also adjusted by rpz policies. But loses cache
* hits. Even though the subquery likely is answered from cache,
* internally in its state machine process. */
if(qstate->rpz_applied)
super->rpz_applied = 1;
if(qstate->rpz_passthru)
super->rpz_passthru = 1;
/* Since the super qstate has a new response, its errinf is removed. */
super->errinf = NULL;
/* Generate a response suitable for the original query. */
if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
@@ -1050,19 +952,11 @@ dns64_inform_super(struct module_qstate* qstate, int id,
log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR);
dns64_adjust_ptr(qstate, super);
}
/* If the sub-query has no cache store, then also the super query. */
if(qstate->fwd_stub_no_cache)
super->fwd_stub_no_cache = 1;
/* Store the generated response in cache. */
if ( super->return_msg && super->return_msg->rep &&
(!super_dq || !super_dq->started_no_cache_store) &&
!qstate->fwd_stub_no_cache &&
!super->rpz_applied && !super->rpz_passthru &&
!super->is_subnet_answer &&
if ( (!super_dq || !super_dq->started_no_cache_store) &&
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
0, super->prefetch_leeway, 0, NULL, super->query_flags,
qstate->qstarttime, qstate->is_valrec))
0, 0, 0, NULL, super->query_flags))
log_err("out of memory");
}
@@ -1100,8 +994,8 @@ dns64_get_mem(struct module_env* env, int id)
*/
static struct module_func_block dns64_block = {
"dns64",
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
&dns64_inform_super, &dns64_clear, &dns64_get_mem
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
&dns64_clear, &dns64_get_mem
};
/**
+34 -55
View File
@@ -316,15 +316,15 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
#else
return -1;
#endif
} else {
if (crypto_box_beforenm(nmkey,
query_header->publickey,
cert->keypair->crypt_secretkey) != 0) {
return -1;
}
}
// Cache the shared secret we just computed.
dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
} else {
if (crypto_box_beforenm(nmkey,
query_header->publickey,
cert->keypair->crypt_secretkey) != 0) {
return -1;
}
}
// Cache the shared secret we just computed.
dnsc_shared_secret_cache_insert(env->shared_secrets_cache,
key,
hash,
nmkey);
@@ -361,7 +361,7 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
len -= DNSCRYPT_QUERY_HEADER_SIZE;
while (len>0 && *sldns_buffer_at(buffer, --len) == 0)
while (*sldns_buffer_at(buffer, --len) == 0)
;
if (*sldns_buffer_at(buffer, len) != 0x80) {
@@ -435,14 +435,27 @@ dnscrypt_hrtime(void)
/**
* Add the server nonce part to once.
* The nonce is made half of client nonce and the second half of the server
* The nonce is made half of client nonce and the seconf half of the server
* nonce, both of them of size crypto_box_HALF_NONCEBYTES.
* \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES
*/
static void
add_server_nonce(uint8_t *nonce)
{
randombytes_buf(nonce + crypto_box_HALF_NONCEBYTES, 8/*tsn*/+4/*suffix*/);
uint64_t ts;
uint64_t tsn;
uint32_t suffix;
ts = dnscrypt_hrtime();
// TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
// unclear if we really need it, so skipping it for now.
tsn = (ts << 10) | (randombytes_random() & 0x3ff);
#if (BYTE_ORDER == LITTLE_ENDIAN)
tsn =
(((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
#endif
memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
suffix = randombytes_random();
memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
}
/**
@@ -474,18 +487,10 @@ dnscrypt_server_curve(const dnsccert *cert,
uint8_t *const buf = sldns_buffer_begin(buffer);
size_t len = sldns_buffer_limit(buffer);
if(len + DNSCRYPT_REPLY_HEADER_SIZE > sldns_buffer_capacity(buffer))
return -1;
sldns_buffer_clear(buffer);
if(udp){
if (max_len > max_reply_size)
max_len = max_reply_size;
}
if(max_len > sldns_buffer_capacity(buffer))
max_len = sldns_buffer_capacity(buffer);
if(max_len > 65535)
max_len = 65535;
memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
@@ -528,7 +533,6 @@ dnscrypt_server_curve(const dnsccert *cert,
DNSCRYPT_MAGIC_HEADER_LEN,
nonce,
crypto_box_NONCEBYTES);
sldns_buffer_flip(buffer);
sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
return 0;
}
@@ -672,8 +676,6 @@ dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
}
dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
for (i = 0U; i < dnscenv->signed_certs_count; i++) {
if(!certs[i].keypair)
continue;
if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
return &certs[i];
@@ -685,7 +687,7 @@ dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
/**
* Insert local-zone and local-data into configuration.
* In order to be able to serve certs over TXT, we can reuse the local-zone and
* local-data config option. The zone and qname are inferred from the
* local-data config option. The zone and qname are infered from the
* provider_name and the content of the TXT record from the certificate content.
* returns the number of certificate TXT record that were loaded.
* < 0 in case of error.
@@ -730,11 +732,6 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
);
continue;
}
if((unsigned)strlen(dnscenv->provider_name) >= (unsigned)0xffff0000) {
/* guard against integer overflow in rrlen calculation */
verbose(VERB_OPS, "cert #%" PRIu32 " is too long", serial);
continue;
}
rrlen = strlen(dnscenv->provider_name) +
strlen(ttl_class_type) +
4 * sizeof(struct SignedCert) + // worst case scenario
@@ -749,9 +746,9 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
for(j=0; j<sizeof(struct SignedCert); j++) {
int c = (int)*((const uint8_t *) cert + j);
if (isprint(c) && c != '"' && c != '\\') {
snprintf(rr + strlen(rr), rrlen - strlen(rr), "%c", c);
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
} else {
snprintf(rr + strlen(rr), rrlen - strlen(rr), "\\%03d", c);
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
}
}
verbose(VERB_OPS,
@@ -760,7 +757,7 @@ dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
" to local-data to config: %s",
serial, rr
);
snprintf(rr + strlen(rr), rrlen - strlen(rr), "\"");
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
cfg_strlist_insert(&cfg->local_data, strdup(rr));
free(rr);
}
@@ -815,7 +812,6 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
sizeof *env->keypairs);
env->certs = sodium_allocarray(env->signed_certs_count,
sizeof *env->certs);
memset(env->certs, 0, env->signed_certs_count * sizeof(*env->certs));
cert_id = 0U;
keypair_id = 0U;
@@ -842,14 +838,7 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
if(memcmp(current_keypair->crypt_publickey,
env->signed_certs[c].server_publickey,
crypto_box_PUBLICKEYBYTES) == 0) {
dnsccert* current_cert;
if(cert_id >= env->signed_certs_count) {
log_err("dnscrypt: secret key %s matches a cert that "
"is already bound to another key (duplicate "
"dnscrypt-secret-key?)", head->str);
return -1;
}
current_cert = &env->certs[cert_id++];
dnsccert *current_cert = &env->certs[cert_id++];
found_cert = 1;
current_cert->keypair = current_keypair;
memcpy(current_cert->magic_query,
@@ -882,17 +871,15 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
return cert_id;
}
#ifdef SODIUM_MISUSE_HANDLER
static void
sodium_misuse_handler(void)
{
fatal_exit(
"dnscrypt: libsodium could not be initialized, this typically"
" happens when no good source of entropy is found. If you run"
" unbound in a chroot, make sure /dev/urandom is available. See"
" unbound in a chroot, make sure /dev/random is available. See"
" https://www.unbound.net/documentation/unbound.conf.html");
}
#endif
/**
@@ -931,13 +918,12 @@ dnsc_handle_curved_request(struct dnsc_env* dnscenv,
}
int
dnsc_handle_uncurved_request(struct comm_reply *repinfo,
struct sldns_buffer* buffer)
dnsc_handle_uncurved_request(struct comm_reply *repinfo)
{
if(!repinfo->c->dnscrypt) {
return 1;
}
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, buffer);
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
if(!repinfo->is_dnscrypted) {
return 1;
}
@@ -983,19 +969,12 @@ dnsc_create(void)
int
dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
{
int nkeys;
if(dnsc_parse_certs(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: no cert file loaded");
}
nkeys = dnsc_parse_keys(env, cfg);
if(nkeys <= 0) {
if(dnsc_parse_keys(env, cfg) <= 0) {
fatal_exit("dnsc_apply_cfg: no key file loaded");
}
if((size_t)nkeys < env->signed_certs_count) {
fatal_exit("dnsc_apply_cfg: %u dnscrypt-provider-cert file(s) have no "
"matching dnscrypt-secret-key",
(unsigned)(env->signed_certs_count - (size_t)nkeys));
}
randombytes_buf(env->hash_key, sizeof env->hash_key);
env->provider_name = cfg->dnscrypt_provider;
+3 -4
View File
@@ -114,7 +114,7 @@ void dnsc_delete(struct dnsc_env *env);
/**
* handle a crypted dnscrypt request.
* Determine whether or not a query is coming over the dnscrypt listener and
* Determine wether or not a query is coming over the dnscrypt listener and
* attempt to uncurve it or detect if it is a certificate query.
* return 0 in case of failure.
*/
@@ -122,14 +122,13 @@ int dnsc_handle_curved_request(struct dnsc_env* dnscenv,
struct comm_reply* repinfo);
/**
* handle an unencrypted dnscrypt request.
* Determine whether or not a query is going over the dnscrypt channel and
* Determine wether or not a query is going over the dnscrypt channel and
* attempt to curve it unless it was not crypted like when it is a
* certificate query.
* \return 0 in case of failure.
*/
int dnsc_handle_uncurved_request(struct comm_reply *repinfo,
struct sldns_buffer* buffer);
int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
/**
* Computes the size of the shared secret cache entry.
+1 -1
View File
@@ -11,7 +11,7 @@ AC_DEFUN([dnsc_DNSCRYPT],
[opt_dnscrypt=$enableval], [opt_dnscrypt=no])
if test "x$opt_dnscrypt" != "xno"; then
AC_ARG_WITH([libsodium], AS_HELP_STRING([--with-libsodium=path],
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path],
[Path where libsodium is installed, for dnscrypt]), [
CFLAGS="$CFLAGS -I$withval/include"
LDFLAGS="$LDFLAGS -L$withval/lib"
+119 -244
View File
@@ -49,12 +49,13 @@
#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 {
@@ -86,35 +87,16 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
return 1;
}
/** See if the message is sent due to dnstap sample rate */
static int
dt_sample_rate_limited(struct dt_env* env)
{
lock_basic_lock(&env->sample_lock);
/* Sampling is every [n] packets. Where n==1, every packet is sent */
if(env->sample_rate > 1) {
int submit = 0;
/* if sampling is engaged... */
if (env->sample_rate_count > env->sample_rate) {
/* once the count passes the limit */
/* submit the message */
submit = 1;
/* and reset the count */
env->sample_rate_count = 0;
}
/* increment count regardless */
env->sample_rate_count++;
lock_basic_unlock(&env->sample_lock);
return !submit;
}
lock_basic_unlock(&env->sample_lock);
return 0;
}
static void
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
{
dt_msg_queue_submit(env->msgqueue, buf, 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);
}
static void
@@ -153,107 +135,108 @@ check_socket_file(const char* socket_path)
}
struct dt_env *
dt_create(struct config_file* cfg)
dt_create(const char *socket_path, unsigned num_workers)
{
#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;
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
char* p = cfg->dnstap_socket_path;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(p,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
p += strlen(cfg->chrootdir);
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
p);
check_socket_file(p);
}
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);
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
if (!env)
return NULL;
lock_basic_init(&env->sample_lock);
env->dtio = dt_io_thread_create();
if(!env->dtio) {
log_err("malloc failure");
dt_delete(env);
return NULL;
}
if(!dt_io_thread_apply_cfg(env->dtio, cfg)) {
dt_delete(env);
return NULL;
}
if(!dt_apply_cfg(env, cfg)) {
dt_delete(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);
free(env);
env = NULL;
}
fstrm_iothr_options_destroy(&fopt);
fstrm_unix_writer_options_destroy(&fuwopt);
fstrm_writer_options_destroy(&fwopt);
return env;
}
static int
static void
dt_apply_identity(struct dt_env *env, struct config_file *cfg)
{
char buf[MAXHOSTNAMELEN+1];
if (!cfg->dnstap_send_identity) {
free(env->identity);
env->identity = NULL;
env->len_identity = 0;
return 1;
}
if (!cfg->dnstap_send_identity)
return;
free(env->identity);
if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
buf[MAXHOSTNAMELEN] = 0;
env->identity = strdup(buf);
} else {
log_err("dt_apply_identity: gethostname() failed: %s",
strerror(errno));
env->identity = NULL;
env->len_identity = 0;
return 0;
fatal_exit("dt_apply_identity: gethostname() failed");
}
} else {
env->identity = strdup(cfg->dnstap_identity);
}
if (env->identity == NULL) {
log_err("dt_apply_identity: strdup() failed");
env->len_identity = 0;
return 0;
}
if (env->identity == NULL)
fatal_exit("dt_apply_identity: strdup() failed");
env->len_identity = (unsigned int)strlen(env->identity);
verbose(VERB_OPS, "dnstap identity field set to \"%s\"",
env->identity);
return 1;
}
static int
static void
dt_apply_version(struct dt_env *env, struct config_file *cfg)
{
if (!cfg->dnstap_send_version) {
free(env->version);
env->version = NULL;
env->len_version = 0;
return 1;
}
if (!cfg->dnstap_send_version)
return;
free(env->version);
if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
env->version = strdup(PACKAGE_STRING);
else
env->version = strdup(cfg->dnstap_version);
if (env->version == NULL) {
log_err("dt_apply_version: strdup() failed");
env->len_version = 0;
return 0;
}
if (env->version == NULL)
fatal_exit("dt_apply_version: strdup() failed");
env->len_version = (unsigned int)strlen(env->version);
verbose(VERB_OPS, "dnstap version field set to \"%s\"",
env->version);
return 1;
}
void
dt_apply_logcfg(struct dt_env *env, struct config_file *cfg)
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
{
if (!cfg->dnstap)
return;
dt_apply_identity(env, cfg);
dt_apply_version(env, cfg);
if ((env->log_resolver_query_messages = (unsigned int)
cfg->dnstap_log_resolver_query_messages))
{
@@ -284,59 +267,24 @@ dt_apply_logcfg(struct dt_env *env, struct config_file *cfg)
{
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
}
lock_basic_lock(&env->sample_lock);
if((env->sample_rate = (unsigned int)cfg->dnstap_sample_rate))
{
verbose(VERB_OPS, "dnstap SAMPLE_RATE enabled and set to \"%d\"", (int)env->sample_rate);
}
lock_basic_unlock(&env->sample_lock);
}
int
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
dt_init(struct dt_env *env)
{
if (!cfg->dnstap)
return 1;
dt_apply_logcfg(env, cfg);
if(!dt_apply_identity(env, cfg))
return 0;
if(!dt_apply_version(env, cfg))
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
if (env->ioq == NULL)
return 0;
return 1;
}
int
dt_init(struct dt_env *env, struct comm_base* base)
{
env->msgqueue = dt_msg_queue_create(base);
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;
dt_io_thread_delete(env->dtio);
lock_basic_destroy(&env->sample_lock);
verbose(VERB_OPS, "closing dnstap socket");
fstrm_iothr_destroy(&env->iothr);
free(env->identity);
free(env->version);
free(env);
@@ -366,96 +314,51 @@ dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
static void
dt_msg_fill_net(struct dt_msg *dm,
struct sockaddr_storage *qs,
struct sockaddr_storage *rs,
struct sockaddr_storage *ss,
enum comm_point_type cptype,
void *cpssl,
ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
uint32_t *qport, protobuf_c_boolean *has_qport,
ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
uint32_t *rport, protobuf_c_boolean *has_rport)
ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
uint32_t *port, protobuf_c_boolean *has_port)
{
log_assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET);
if (qs->ss_family == AF_INET6) {
struct sockaddr_in6 *q = (struct sockaddr_in6 *) qs;
log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
if (ss->ss_family == AF_INET6) {
struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
qaddr->data = q->sin6_addr.s6_addr;
qaddr->len = 16; /* IPv6 */
*has_qaddr = 1;
addr->data = s->sin6_addr.s6_addr;
addr->len = 16; /* IPv6 */
*has_addr = 1;
/* port: query_port or response_port */
*qport = ntohs(q->sin6_port);
*has_qport = 1;
} else if (qs->ss_family == AF_INET) {
struct sockaddr_in *q = (struct sockaddr_in *) qs;
*port = ntohs(s->sin6_port);
*has_port = 1;
} else if (ss->ss_family == AF_INET) {
struct sockaddr_in *s = (struct sockaddr_in *) ss;
/* socket_family */
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
dm->m.has_socket_family = 1;
/* addr: query_address or response_address */
qaddr->data = (uint8_t *) &q->sin_addr.s_addr;
qaddr->len = 4; /* IPv4 */
*has_qaddr = 1;
addr->data = (uint8_t *) &s->sin_addr.s_addr;
addr->len = 4; /* IPv4 */
*has_addr = 1;
/* port: query_port or response_port */
*qport = ntohs(q->sin_port);
*has_qport = 1;
*port = ntohs(s->sin_port);
*has_port = 1;
}
/*
* This block is to fill second set of fields in DNSTAP-message defined as request_/response_ names.
* Additional responsive structure is: struct sockaddr_storage *rs
*/
if (rs && rs->ss_family == AF_INET6) {
struct sockaddr_in6 *r = (struct sockaddr_in6 *) rs;
/* addr: query_address or response_address */
raddr->data = r->sin6_addr.s6_addr;
raddr->len = 16; /* IPv6 */
*has_raddr = 1;
/* port: query_port or response_port */
*rport = ntohs(r->sin6_port);
*has_rport = 1;
} else if (rs && rs->ss_family == AF_INET) {
struct sockaddr_in *r = (struct sockaddr_in *) rs;
/* addr: query_address or response_address */
raddr->data = (uint8_t *) &r->sin_addr.s_addr;
raddr->len = 4; /* IPv4 */
*has_raddr = 1;
/* port: query_port or response_port */
*rport = ntohs(r->sin_port);
*has_rport = 1;
}
log_assert(cptype == comm_udp || cptype == comm_tcp);
if (cptype == comm_udp) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
dm->m.has_socket_protocol = 1;
} else if (cptype == comm_tcp) {
if (cpssl == NULL) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
dm->m.has_socket_protocol = 1;
} else {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT;
dm->m.has_socket_protocol = 1;
}
} else if (cptype == comm_http) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH;
dm->m.has_socket_protocol = 1;
} else {
/* other socket protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
dm->m.has_socket_protocol = 1;
}
@@ -464,21 +367,13 @@ dt_msg_fill_net(struct dt_msg *dm,
void
dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
sldns_buffer *qmsg,
struct timeval* tstamp)
sldns_buffer *qmsg)
{
struct dt_msg dm;
struct timeval qtime;
if(dt_sample_rate_limited(env))
return;
if(tstamp)
memcpy(&qtime, tstamp, sizeof(qtime));
else gettimeofday(&qtime, NULL);
gettimeofday(&qtime, NULL);
/* type */
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_QUERY);
@@ -491,13 +386,11 @@ dt_msg_send_client_query(struct dt_env *env,
/* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
/* socket_family, socket_protocol, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, cptype,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port);
&dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
@@ -506,17 +399,12 @@ dt_msg_send_client_query(struct dt_env *env,
void
dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
sldns_buffer *rmsg)
{
struct dt_msg dm;
struct timeval rtime;
if(dt_sample_rate_limited(env))
return;
gettimeofday(&rtime, NULL);
/* type */
@@ -530,12 +418,11 @@ dt_msg_send_client_response(struct dt_env *env,
/* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
/* socket_family, socket_protocol, query_address, query_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, qsock, cptype,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port);
&dm.m.query_port, &dm.m.has_query_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
@@ -544,9 +431,7 @@ dt_msg_send_client_response(struct dt_env *env,
void
dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
sldns_buffer *qmsg)
{
@@ -554,14 +439,11 @@ dt_msg_send_outside_query(struct dt_env *env,
struct timeval qtime;
uint16_t qflags;
if(dt_sample_rate_limited(env))
return;
gettimeofday(&qtime, NULL);
qflags = sldns_buffer_read_u16_at(qmsg, 2);
/* type */
if ((qflags & BIT_RD)) {
if (qflags & BIT_RD) {
if (!env->log_forwarder_query_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY);
@@ -584,12 +466,11 @@ dt_msg_send_outside_query(struct dt_env *env,
/* query_message */
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
/* socket_family, socket_protocol, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, cptype,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
&dm.m.response_port, &dm.m.has_response_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
@@ -597,28 +478,23 @@ dt_msg_send_outside_query(struct dt_env *env,
void
dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
const struct timeval *rtime,
sldns_buffer *rmsg)
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
const struct timeval *rtime,
sldns_buffer *rmsg)
{
struct dt_msg dm;
uint16_t qflags;
if(dt_sample_rate_limited(env))
return;
(void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
log_assert(qbuf_len >= sizeof(qflags));
memcpy(&qflags, qbuf, sizeof(qflags));
qflags = ntohs(qflags);
/* type */
if ((qflags & BIT_RD)) {
if (qflags & BIT_RD) {
if (!env->log_forwarder_response_messages)
return;
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
@@ -646,12 +522,11 @@ dt_msg_send_outside_response(struct dt_env *env,
/* response_message */
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
/* socket_family, socket_protocol, response_address, response_port */
log_assert(cptype == comm_udp || cptype == comm_tcp);
dt_msg_fill_net(&dm, rsock, cptype,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port);
&dm.m.response_port, &dm.m.has_response_port);
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
dt_send(env, dm.buf, dm.len_buf);
+15 -49
View File
@@ -39,18 +39,17 @@
#ifdef USE_DNSTAP
#include "util/locks.h"
struct config_file;
struct fstrm_io;
struct fstrm_queue;
struct sldns_buffer;
struct dt_msg_queue;
struct dt_env {
/** the io thread (made by the struct daemon) */
struct dt_io_thread* dtio;
/** dnstap I/O thread */
struct fstrm_iothr *iothr;
/** valid in worker struct, not in daemon struct, the per-worker
* message list */
struct dt_msg_queue* msgqueue;
/** dnstap I/O thread input queue */
struct fstrm_iothr_queue *ioq;
/** dnstap "identity" field, NULL if disabled */
char *identity;
@@ -76,13 +75,6 @@ struct dt_env {
unsigned log_forwarder_query_messages : 1;
/** whether to log Message/FORWARDER_RESPONSE */
unsigned log_forwarder_response_messages : 1;
/** lock on sample count */
lock_basic_type sample_lock;
/** rate limit value from config, samples 1/N messages */
unsigned int sample_rate;
/** rate limit counter */
unsigned int sample_rate_count;
};
/**
@@ -92,40 +84,28 @@ 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 cfg: with config settings.
* @param socket_path: path to dnstap logging socket, must be non-NULL.
* @param num_workers: number of worker threads, must be > 0.
* @return dt_env object, NULL on failure.
*/
struct dt_env *
dt_create(struct config_file* cfg);
dt_create(const char *socket_path, unsigned num_workers);
/**
* Apply config settings.
* @param env: dnstap environment object.
* @param cfg: new config settings.
* @return false on failure.
*/
int dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
/**
* Apply config settings for log enable for message types.
* @param env: dnstap environment object.
* @param cfg: new config settings.
*/
void dt_apply_logcfg(struct dt_env *env, struct config_file *cfg);
void
dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
/**
* Initialize per-worker state in dnstap environment object.
* @param env: dnstap environment object to initialize, created with dt_create().
* @param base: event base for wakeup timer.
* @return: true on success, false on failure.
*/
int
dt_init(struct dt_env *env, struct comm_base* base);
/**
* Deletes the per-worker state created by dt_init
*/
void dt_deinit(struct dt_env *env);
dt_init(struct dt_env *env);
/**
* Delete dnstap environment object. Closes dnstap I/O socket and deletes all
@@ -138,34 +118,26 @@ dt_delete(struct dt_env *env);
* Create and send a new dnstap "Message" event of type CLIENT_QUERY.
* @param env: dnstap environment object.
* @param qsock: address/port of client.
* @param rsock: local (service) address/port.
* @param cptype: comm_udp or comm_tcp.
* @param qmsg: query message.
* @param tstamp: timestamp or NULL if none provided.
*/
void
dt_msg_send_client_query(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
struct sldns_buffer *qmsg,
struct timeval* tstamp);
struct sldns_buffer *qmsg);
/**
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
* @param env: dnstap environment object.
* @param qsock: address/port of client.
* @param rsock: local (service) address/port.
* @param cptype: comm_udp or comm_tcp.
* @param rmsg: response message.
*/
void
dt_msg_send_client_response(struct dt_env *env,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
void *cpssl,
struct sldns_buffer *rmsg);
/**
@@ -173,8 +145,7 @@ dt_msg_send_client_response(struct dt_env *env,
* FORWARDER_QUERY. The type used is dependent on the value of the RD bit
* in the query header.
* @param env: dnstap environment object.
* @param rsock: address/port of server (upstream) the query is being sent to.
* @param qsock: address/port of server (local) the query is being sent from.
* @param rsock: address/port of server the query is being sent to.
* @param cptype: comm_udp or comm_tcp.
* @param zone: query zone.
* @param zone_len: length of zone.
@@ -183,9 +154,7 @@ dt_msg_send_client_response(struct dt_env *env,
void
dt_msg_send_outside_query(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
struct sldns_buffer *qmsg);
@@ -194,8 +163,7 @@ dt_msg_send_outside_query(struct dt_env *env,
* FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit
* in the query header.
* @param env: dnstap environment object.
* @param rsock: address/port of server (upstream) the response was received from.
* @param qsock: address/port of server (local) the response was received to.
* @param rsock: address/port of server the response was received from.
* @param cptype: comm_udp or comm_tcp.
* @param zone: query zone.
* @param zone_len: length of zone.
@@ -208,9 +176,7 @@ dt_msg_send_outside_query(struct dt_env *env,
void
dt_msg_send_outside_response(struct dt_env *env,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
void *cpssl,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
+45 -97
View File
@@ -5,104 +5,52 @@
# Check for required dnstap libraries and add dnstap configure args.
AC_DEFUN([dt_DNSTAP],
[
AC_ARG_ENABLE([dnstap],
AS_HELP_STRING([--enable-dnstap],
[Enable dnstap support (requires protobuf-c)]),
[opt_dnstap=$enableval],
[opt_dnstap=no])
AC_ARG_ENABLE([dnstap],
AS_HELP_STRING([--enable-dnstap],
[Enable dnstap support (requires fstrm, protobuf-c)]),
[opt_dnstap=$enableval], [opt_dnstap=no])
AC_ARG_WITH([dnstap-socket-path],
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
[set default dnstap socket path]),
[opt_dnstap_socket_path=$withval],
[opt_dnstap_socket_path="$1"])
AC_ARG_WITH([dnstap-socket-path],
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
[set default dnstap socket path]),
[opt_dnstap_socket_path=$withval], [opt_dnstap_socket_path="$1"])
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC], [protoc])
# 'protoc-c' is deprecated. We use 'protoc' instead. If it can not be
# found, try 'protoc-c'.
if test -z "$PROTOC"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
else
PROTOC_C="$PROTOC"
fi
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([[The protoc or protoc-c program was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c to provide protoc or protoc-c]])
fi
# Check for protoc-gen-c plugin
AC_PATH_PROG([PROTOC_GEN_C], [protoc-gen-c])
if test -z "$PROTOC_GEN_C"; then
AC_MSG_ERROR([[The protoc-gen-c plugin was not found. It is needed for dnstap, use --disable-dnstap, or install protobuf-c-compiler to provide protoc-gen-c]])
fi
# Test that protoc-gen-c actually works
AC_MSG_CHECKING([if protoc-gen-c plugin works])
cat > conftest.proto << EOF
syntax = "proto2";
message TestMessage {
optional string test_field = 1;
}
EOF
if $PROTOC_C --c_out=. conftest.proto >/dev/null 2>&1; then
AC_MSG_RESULT([yes])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
else
AC_MSG_RESULT([no])
rm -f conftest.proto conftest.pb-c.c conftest.pb-c.h
AC_MSG_ERROR([[The protoc-gen-c plugin is not working properly. Please ensure protobuf-c-compiler is properly installed]])
fi
AC_ARG_WITH([protobuf-c],
AS_HELP_STRING([--with-protobuf-c=path], [Path where protobuf-c is installed, for dnstap]),
[
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I$withval/include/google"
else
CFLAGS="$CFLAGS -I$withval/include"
fi
LDFLAGS="$LDFLAGS -L$withval/lib"
],
[
if test -n "$PKG_CONFIG"; then
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
[
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
LIBS="$LIBS $PROTOBUFC_LIBS"
],
[
# pkg-config failed; try falling back to known values
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
else
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
fi
fi
]
)
else
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
fi
fi
]
)
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
AC_MSG_ERROR([The protobuf-c library was not found. Please install the development libraries for protobuf-c!]))
$2
else
$3
if test "x$opt_dnstap" != "xno"; then
AC_PATH_PROG([PROTOC_C], [protoc-c])
if test -z "$PROTOC_C"; then
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
fi
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
[Path where protobuf-c is installed, for dnstap]), [
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I$withval/include/google"
else
CFLAGS="$CFLAGS -I$withval/include"
fi
LDFLAGS="$LDFLAGS -L$withval/lib"
], [
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/include/google"
else
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
CFLAGS="$CFLAGS -I/usr/local/include/google"
LDFLAGS="$LDFLAGS -L/usr/local/lib"
fi
fi
])
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
else
$3
fi
])
+7 -75
View File
@@ -13,8 +13,8 @@
// with this file. If not, see:
//
// <http://creativecommons.org/publicdomain/zero/1.0/>.
syntax = "proto2";
package dnstap;
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
@@ -56,60 +56,11 @@ enum SocketFamily {
INET6 = 2; // IPv6 (RFC 2460)
}
// SocketProtocol: the protocol used to transport a DNS message.
// SocketProtocol: the transport protocol of a socket. This specifies how to
// interpret "transport port" fields.
enum SocketProtocol {
UDP = 1; // DNS over UDP transport (RFC 1035 section 4.2.1)
TCP = 2; // DNS over TCP transport (RFC 1035 section 4.2.2)
DOT = 3; // DNS over TLS (RFC 7858)
DOH = 4; // DNS over HTTPS (RFC 8484)
DNSCryptUDP = 5; // DNSCrypt over UDP (https://dnscrypt.info/protocol)
DNSCryptTCP = 6; // DNSCrypt over TCP (https://dnscrypt.info/protocol)
DOQ = 7; // DNS over QUIC (RFC 9250)
}
// Policy: information about any name server operator policy
// applied to the processing of a DNS message.
message Policy {
// Match: what aspect of the message or message exchange
// triggered the application of the Policy.
enum Match {
QNAME = 1; // Name in question section of query
CLIENT_IP = 2; // Client IP address
RESPONSE_IP = 3; // Address in A/AAAA RRSet
NS_NAME = 4; // Authoritative name server, by name
NS_IP = 5; // Authoritative name server, by IP address
}
// The Action taken to implement the Policy.
enum Action {
NXDOMAIN = 1; // Respond with NXDOMAIN
NODATA = 2; // Respond with empty answer section
PASS = 3; // Do not alter the response (passthrough)
DROP = 4; // Do not respond.
TRUNCATE = 5; // Truncate UDP response, forcing TCP retry
LOCAL_DATA = 6; // Respond with local data from policy
}
// type: the type of policy applied, e.g. "RPZ" for a
// policy from a Response Policy Zone.
optional string type = 1;
// rule: the rule matched by the message.
//
// In a RPZ context, this is the owner name of the rule in
// the Response Policy Zone in wire format.
optional bytes rule = 2;
// action: the policy action taken in response to the
// rule match.
optional Action action = 3;
// match: the feature of the message exchange which matched the rule.
optional Match match = 4;
// The matched value. Format depends on the matched feature .
optional bytes value = 5;
UDP = 1; // User Datagram Protocol (RFC 768)
TCP = 2; // Transmission Control Protocol (RFC 793)
}
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
@@ -207,24 +158,6 @@ message Message {
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
// stub resolver, from the perspective of the stub resolver.
STUB_RESPONSE = 10;
// TOOL_QUERY is a DNS query message sent from a DNS software tool to a
// DNS server, from the perspective of the tool.
TOOL_QUERY = 11;
// TOOL_RESPONSE is a DNS response message received by a DNS software
// tool from a DNS server, from the perspective of the tool.
TOOL_RESPONSE = 12;
// UPDATE_QUERY is a Dynamic DNS Update request (RFC 2136) received
// by an authoritative name server, from the perspective of the
// authoritative name server.
UPDATE_QUERY = 13;
// UPDATE_RESPONSE is a Dynamic DNS Update response (RFC 2136) sent
// from an authoritative name server, from the perspective of the
// authoritative name server.
UPDATE_RESPONSE = 14;
}
// One of the Type values described above.
@@ -282,9 +215,6 @@ message Message {
// The responder's original wire-format DNS response message, verbatim.
optional bytes response_message = 14;
// Operator policy applied to the processing of this message, if any.
optional Policy policy = 15;
}
// All fields except for 'type' in the Message schema are optional.
@@ -306,6 +236,7 @@ message Message {
// RESOLVER_QUERY:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_message
// query_time_sec, query_time_nsec
// query_zone
@@ -313,6 +244,7 @@ message Message {
// RESOLVER_RESPONSE:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_time_sec, query_time_nsec
// query_zone
// response_address, response_port
-236
View File
@@ -1,236 +0,0 @@
/*
* 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
View File
@@ -1,194 +0,0 @@
/*
* 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 */
-2240
View File
File diff suppressed because it is too large Load Diff
-360
View File
@@ -1,360 +0,0 @@
/*
* 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;
struct comm_base;
/**
* 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;
/** number of messages in the queue */
int msgcount;
/** 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;
/** the wakeup timer for dtio, on worker event base */
struct comm_timer* wakeup_timer;
};
/**
* 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;
#ifdef HAVE_GETTID
/** thread tid, the LWP id */
pid_t thread_tid;
/** if logging should include the LWP id */
int thread_tid_log;
#endif
/** if the io processing has started */
int started;
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
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;
/** lock on wakeup_timer_enabled */
lock_basic_type wakeup_timer_lock;
/** if wakeup timer is enabled in some thread */
int wakeup_timer_enabled;
/** 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.
* @param base: event base for wakeup timer.
* @return NULL on malloc failure or a new queue (not locked).
*/
struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base);
/**
* 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);
/** timer callback to wakeup dtio thread to process messages */
void mq_wakeup_cb(void* arg);
/**
* Create IO thread.
* @return new io thread object. not yet started. or NULL malloc failure.
*/
struct dt_io_thread* dt_io_thread_create(void);
/**
* Delete the IO thread structure.
* @param dtio: the io thread that is deleted. It must not be running.
*/
void dt_io_thread_delete(struct dt_io_thread* dtio);
/**
* Apply config to the dtio thread
* @param dtio: io thread, not yet started.
* @param cfg: config file struct.
* @return false on malloc failure.
*/
int dt_io_thread_apply_cfg(struct dt_io_thread* dtio,
struct config_file *cfg);
/**
* Register a msg queue to the io thread. It will be polled to see if
* there are messages and those then get removed and sent, when the thread
* is running.
* @param dtio: the io thread.
* @param mq: message queue to register.
* @return false on failure (malloc failure).
*/
int dt_io_thread_register_queue(struct dt_io_thread* dtio,
struct dt_msg_queue* mq);
/**
* Unregister queue from io thread.
* @param dtio: the io thread.
* @param mq: message queue.
*/
void dt_io_thread_unregister_queue(struct dt_io_thread* dtio,
struct dt_msg_queue* mq);
/**
* Start the io thread
* @param dtio: the io thread.
* @param event_base_nothr: the event base to attach the events to, in case
* we are running without threads. With threads, this is ignored
* and a thread is started to process the dnstap log messages.
* @param numworkers: number of worker threads. The dnstap io thread is
* that number +1 as the threadnumber (in logs).
* @return false on failure.
*/
int dt_io_thread_start(struct dt_io_thread* dtio, void* event_base_nothr,
int numworkers);
/**
* Stop the io thread
* @param dtio: the io thread.
*/
void dt_io_thread_stop(struct dt_io_thread* dtio);
/** callback for the dnstap reconnect, to start reconnecting to output */
void dtio_reconnect_timeout_cb(int fd, short bits, void* arg);
/** callback for the dnstap events, to write to the output */
void dtio_output_cb(int fd, short bits, void* arg);
/** callback for the dnstap commandpipe, to stop the dnstap IO */
void dtio_cmd_cb(int fd, short bits, void* arg);
/** callback for the timer when the thread stops and wants to finish up */
void dtio_stop_timer_cb(int fd, short bits, void* arg);
/** callback for the output when the thread stops and wants to finish up */
void dtio_stop_ev_cb(int fd, short bits, void* arg);
/** callback for unbound-dnstap-socket */
void dtio_tap_callback(int fd, short bits, void* arg);
/** callback for unbound-dnstap-socket */
void dtio_mainfdcallback(int fd, short bits, void* arg);
#endif /* DTSTREAM_H */
File diff suppressed because it is too large Load Diff
+15 -5467
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -39,7 +39,6 @@ RFC 4343: case insensitive handling of domain names.
RFC 4509: SHA256 DS hash.
RFC 4592: wildcards.
RFC 4697: No DNS Resolution Misbehavior.
RFC 5001: DNS Name Server Identifier (NSID) Option
RFC 5011: update of trust anchors with timers.
RFC 5155: NSEC3, NSEC3PARAM types
RFC 5358: reflectors-are-evil: access control list for recursive
+6 -5
View File
@@ -19,10 +19,11 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
* Make and install: ./configure; make; make install
* --with-libevent=/path/to/libevent
Can be set to either the system install or the build directory.
--with-libevent=no gives a builtin alternative implementation.
Libevent is enabled by default, it is useful when having many
(thousands) of outgoing ports. This improves randomization and spoof
resistance. It also allows a higher number of outgoing queries.
--with-libevent=no (default) gives a builtin alternative
implementation. libevent is useful when having many (thousands)
of outgoing ports. This improves randomization and spoof
resistance. For the default of 16 ports the builtin alternative
works well and is a little faster.
* --with-libexpat=/path/to/libexpat
Can be set to the install directory of libexpat.
* --without-pthreads
@@ -98,7 +99,7 @@ o If you are not receiving the correct source IP address on replies (e.g.
the config file is an alternative. The interface-automatic option uses
non portable socket options, Linux and FreeBSD should work fine.
o The warning 'openssl has no entropy, seeding with time', with chroot
enabled, may be solved with a symbolic link to /dev/urandom from <chrootdir>.
enabled, may be solved with a symbolic link to /dev/random from <chrootdir>.
o On Solaris 5.10 some libtool packages from repositories do not work with
gcc, showing errors gcc: unrecognized option `-KPIC'
To solve this do ./configure libtool=./libtool [your options...].

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