mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47cc931542 | ||
|
|
e2866cb6f6 |
@@ -1 +0,0 @@
|
||||
testdata/*.[0-9] linguist-documentation
|
||||
@@ -1,2 +0,0 @@
|
||||
github: [NLnetLabs]
|
||||
custom: ['https://nlnetlabs.nl/funding/']
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -1,351 +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:
|
||||
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, armv7
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: armv7-apple-ios
|
||||
OPENSSL_HOST: ios-cross
|
||||
IOS_SDK: iPhoneOS
|
||||
IOS_CPU: armv7s
|
||||
test_ios: "yes"
|
||||
config: "no"
|
||||
make: "no"
|
||||
- name: Apple iPhone on iOS, arm64
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: aarch64-apple-ios
|
||||
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, i386
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: i386-apple-ios
|
||||
OPENSSL_HOST: iphoneos-cross
|
||||
IOS_SDK: iPhoneSimulator
|
||||
IOS_CPU: i386
|
||||
test_ios: "yes"
|
||||
config: "no"
|
||||
make: "no"
|
||||
- name: iPhoneSimulator on OS X, x86_64
|
||||
os: macos-latest
|
||||
AUTOTOOLS_HOST: x86_64-apple-ios
|
||||
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"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
- name: test_windows
|
||||
if: ${{ matrix.test_windows == 'yes' }}
|
||||
shell: bash
|
||||
run: |
|
||||
export unboundpath=`pwd`
|
||||
echo unboundpath=${unboundpath}
|
||||
cd ..
|
||||
export prepath=`pwd`
|
||||
echo prepath=${prepath}
|
||||
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
|
||||
make 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 expat-2.2.10.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_10/expat-2.2.10.tar.gz
|
||||
tar xzf expat-2.2.10.tar.gz
|
||||
cd expat-2.2.10
|
||||
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
|
||||
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
|
||||
# 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: 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)
|
||||
@@ -1,21 +0,0 @@
|
||||
name: ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: configure
|
||||
run: ./configure --enable-debug
|
||||
- name: make
|
||||
run: make
|
||||
- name: make test
|
||||
run: make test
|
||||
-64
@@ -1,64 +0,0 @@
|
||||
*.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
|
||||
/doc/unbound-checkconf.8
|
||||
/doc/unbound-control.8
|
||||
/doc/unbound-host.1
|
||||
/doc/unbound.8
|
||||
/doc/unbound.conf.5
|
||||
/libtool
|
||||
/libunbound.la
|
||||
/_unbound.la
|
||||
/smallapp/unbound-control-setup.sh
|
||||
/unbound
|
||||
/unbound-anchor
|
||||
/unbound-checkconf
|
||||
/unbound-control
|
||||
/unbound-control-setup
|
||||
/unbound-host
|
||||
/unbound.h
|
||||
/asynclook
|
||||
/delayer
|
||||
/dohclient
|
||||
/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
@@ -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
|
||||
@@ -18,13 +18,13 @@ 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.
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
+698
-1109
File diff suppressed because it is too large
Load Diff
@@ -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.
|
||||
@@ -1,42 +0,0 @@
|
||||
# Unbound
|
||||
|
||||
[](https://github.com/NLnetLabs/unbound/actions)
|
||||
[](https://repology.org/project/unbound/versions)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
|
||||
[](https://unbound.readthedocs.io/en/latest/?badge=latest)
|
||||
[](https://fosstodon.org/@nlnetlabs)
|
||||
|
||||
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. Don’t hesitate to
|
||||
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
|
||||
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
|
||||
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 (10000)
|
||||
outgoing ports. By default max 256 ports are opened at the same time and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
|
||||
Use the `--with-libevent` configure option to compile Unbound with libevent
|
||||
support.
|
||||
|
||||
## Unbound configuration
|
||||
|
||||
All of Unbound's configuration options are described in the man pages, which
|
||||
will be installed and are available on the Unbound
|
||||
[documentation page](https://unbound.docs.nlnetlabs.nl/).
|
||||
|
||||
An example configuration file is located in
|
||||
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
|
||||
-31
@@ -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/
|
||||
@@ -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,19 @@ 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],[])
|
||||
if test $available_major -ne $required_major \
|
||||
-o $available_minor -ne $required_minor \
|
||||
-o $available_patch -lt $required_patch ; 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
+1139
-1975
File diff suppressed because it is too large
Load Diff
+106
-273
@@ -2,33 +2,7 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 48
|
||||
# 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).
|
||||
# 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
|
||||
# 2015-12-11 FLTO check for new OSX, clang.
|
||||
# 2015-11-18 spelling check fix.
|
||||
# 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly.
|
||||
# 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added.
|
||||
# 2015-03-17 AHX_CONFIG_REALLOCARRAY added
|
||||
# 2013-09-19 FLTO help text improved.
|
||||
# Version 25
|
||||
# 2013-07-18 Enable ACX_CHECK_COMPILER_FLAG to test for -Wstrict-prototypes
|
||||
# 2013-06-25 FLTO has --disable-flto option.
|
||||
# 2013-05-03 Update W32_SLEEP for newer mingw that links but not defines it.
|
||||
@@ -47,7 +21,7 @@
|
||||
# 2010-07-02 Add check for ss_family (for minix).
|
||||
# 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS.
|
||||
# 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end.
|
||||
# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS separate, -ldl
|
||||
# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS seperate, -ldl
|
||||
# 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN
|
||||
# 2010-01-20 added AHX_COONFIG_STRLCAT
|
||||
# 2009-07-14 U_CHAR detection improved for windows crosscompile.
|
||||
@@ -118,8 +92,6 @@
|
||||
# ACX_CHECK_MEMCMP_SIGNED - check if memcmp uses signed characters.
|
||||
# AHX_MEMCMP_BROKEN - replace memcmp func for CHECK_MEMCMP_SIGNED.
|
||||
# ACX_CHECK_SS_FAMILY - check for sockaddr_storage.ss_family
|
||||
# ACX_CHECK_PIE - add --enable-pie option and check if works
|
||||
# ACX_CHECK_RELRO_NOW - add --enable-relro-now option and check it
|
||||
#
|
||||
|
||||
dnl Escape backslashes as \\, for C:\ paths, for the C preprocessor defines.
|
||||
@@ -192,7 +164,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
|
||||
@@ -238,7 +210,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
|
||||
@@ -262,7 +234,7 @@ ACX_CHECK_COMPILER_FLAG(xc99, [C99FLAG="-xc99"])
|
||||
|
||||
AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE,
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE,
|
||||
[
|
||||
#include "confdefs.h"
|
||||
#include <stdlib.h>
|
||||
@@ -277,7 +249,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;
|
||||
@@ -297,9 +269,9 @@ int test(void) {
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"])
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_XOPEN_SOURCE_EXTENDED=1 -D_ALL_SOURCE"])
|
||||
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE,
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE,
|
||||
[
|
||||
#include "confdefs.h"
|
||||
#include <stdlib.h>
|
||||
@@ -314,7 +286,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;
|
||||
@@ -334,34 +306,34 @@ int test(void) {
|
||||
a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"])
|
||||
], [CFLAGS="$CFLAGS $C99FLAG -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"])
|
||||
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED($C99FLAG,
|
||||
[
|
||||
#include <stdbool.h>
|
||||
#include <ctype.h>
|
||||
int test(void) {
|
||||
int test() {
|
||||
int a = 0;
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS $C99FLAG"])
|
||||
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE -D_DEFAULT_SOURCE,
|
||||
ACX_CHECK_COMPILER_FLAG_NEEDED(-D_BSD_SOURCE,
|
||||
[
|
||||
#include <ctype.h>
|
||||
|
||||
int test(void) {
|
||||
int test() {
|
||||
int a;
|
||||
a = isascii(32);
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -D_BSD_SOURCE -D_DEFAULT_SOURCE"])
|
||||
], [CFLAGS="$CFLAGS -D_BSD_SOURCE"])
|
||||
|
||||
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;
|
||||
@@ -375,7 +347,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;
|
||||
@@ -390,7 +362,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;
|
||||
@@ -418,7 +390,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;
|
||||
@@ -438,13 +410,13 @@ dnl Check if CC supports -flto.
|
||||
dnl in a way that supports clang and suncc (that flag does something else,
|
||||
dnl but fails to link). It sets it in CFLAGS if it works.
|
||||
AC_DEFUN([ACX_CHECK_FLTO], [
|
||||
AC_ARG_ENABLE([flto], AS_HELP_STRING([--disable-flto], [Disable link-time optimization (gcc specific option)]))
|
||||
AC_ARG_ENABLE([flto], AS_HELP_STRING([--disable-flto], [Disable link-time optimization]))
|
||||
AS_IF([test "x$enable_flto" != "xno"], [
|
||||
AC_MSG_CHECKING([if $CC supports -flto])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -flto"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
if $CC $CFLAGS -o conftest conftest.c 2>&1 | $GREP -e "warning: no debug symbols in executable" -e "warning: object" >/dev/null; then
|
||||
if $CC $CFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
@@ -463,12 +435,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)
|
||||
@@ -480,7 +455,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,11 +472,14 @@ AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE],
|
||||
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.
|
||||
@@ -558,7 +536,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.
|
||||
@@ -656,30 +634,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
|
||||
@@ -687,12 +641,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
|
||||
@@ -700,113 +654,68 @@ 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_CTX_init 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_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_EVP_SHA256], 1,
|
||||
[If you have EVP_sha256])
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
], [
|
||||
AC_MSG_RESULT(no)
|
||||
# check if -lwsock32 or -lgdi32 are needed.
|
||||
BAKLIBS="$LIBS"
|
||||
BAKSSLLIBS="$LIBSSL_LIBS"
|
||||
LIBS="$LIBS -lgdi32 -lws2_32"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
|
||||
LIBS="$LIBS -lgdi32"
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32"
|
||||
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_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
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_CTX_init(void);
|
||||
(void)HMAC_CTX_init();
|
||||
],[
|
||||
AC_DEFINE([HAVE_HMAC_CTX_INIT], 1,
|
||||
[If you have HMAC_CTX_init])
|
||||
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
|
||||
AC_SUBST(HAVE_SSL)
|
||||
AC_SUBST(RUNTIME_PATH)
|
||||
# openssl engine functionality needs dlopen().
|
||||
BAKLIBS="$LIBS"
|
||||
AC_SEARCH_LIBS([dlopen], [dl])
|
||||
if test "$LIBS" != "$BAKLIBS"; then
|
||||
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
|
||||
fi
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT])
|
||||
@@ -815,13 +724,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"
|
||||
])
|
||||
@@ -838,8 +748,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"
|
||||
])
|
||||
@@ -872,7 +783,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;
|
||||
}
|
||||
@@ -897,7 +808,7 @@ char* (*f) () = getaddrinfo;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
int main(void) {
|
||||
int main() {
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@@ -908,32 +819,10 @@ 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
|
||||
:
|
||||
else
|
||||
LIBS="$LIBS -lws2_32"
|
||||
fi
|
||||
LIBS="$LIBS -lws2_32"
|
||||
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(
|
||||
@@ -958,7 +847,6 @@ ac_cv_func_getaddrinfo="no"
|
||||
LIBS="$ORIGLIBS"
|
||||
])
|
||||
)
|
||||
)
|
||||
|
||||
AC_MSG_RESULT($ac_cv_func_getaddrinfo)
|
||||
if test $ac_cv_func_getaddrinfo = yes; then
|
||||
@@ -980,8 +868,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"
|
||||
@@ -1007,7 +895,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
|
||||
@@ -1021,9 +909,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
|
||||
@@ -1152,7 +1037,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
|
||||
@@ -1161,12 +1046,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.
|
||||
@@ -1325,16 +1212,6 @@ struct tm *gmtime_r(const time_t *timep, struct tm *result);
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl provide reallocarray compat prototype.
|
||||
dnl $1: unique name for compat code
|
||||
AC_DEFUN([AHX_CONFIG_REALLOCARRAY],
|
||||
[
|
||||
#ifndef HAVE_REALLOCARRAY
|
||||
#define reallocarray reallocarray$1
|
||||
void* reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl provide w32 compat definition for sleep
|
||||
AC_DEFUN([AHX_CONFIG_W32_SLEEP],
|
||||
[
|
||||
@@ -1374,7 +1251,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
|
||||
])
|
||||
|
||||
@@ -1396,7 +1273,6 @@ AC_DEFUN([ACX_STRIP_EXT_FLAGS],
|
||||
AC_MSG_NOTICE([Stripping extension flags...])
|
||||
ACX_CFLAGS_STRIP(-D_GNU_SOURCE)
|
||||
ACX_CFLAGS_STRIP(-D_BSD_SOURCE)
|
||||
ACX_CFLAGS_STRIP(-D_DEFAULT_SOURCE)
|
||||
ACX_CFLAGS_STRIP(-D__EXTENSIONS__)
|
||||
ACX_CFLAGS_STRIP(-D_POSIX_C_SOURCE=200112)
|
||||
ACX_CFLAGS_STRIP(-D_XOPEN_SOURCE=600)
|
||||
@@ -1412,7 +1288,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.
|
||||
@@ -1424,7 +1300,6 @@ dnl config.h part to define omitted cflags, use with ACX_STRIP_EXT_FLAGS.
|
||||
AC_DEFUN([AHX_CONFIG_EXT_FLAGS],
|
||||
[AHX_CONFIG_FLAG_EXT(-D_GNU_SOURCE)
|
||||
AHX_CONFIG_FLAG_EXT(-D_BSD_SOURCE)
|
||||
AHX_CONFIG_FLAG_EXT(-D_DEFAULT_SOURCE)
|
||||
AHX_CONFIG_FLAG_EXT(-D__EXTENSIONS__)
|
||||
AHX_CONFIG_FLAG_EXT(-D_POSIX_C_SOURCE=200112)
|
||||
AHX_CONFIG_FLAG_EXT(-D_XOPEN_SOURCE=600)
|
||||
@@ -1499,46 +1374,4 @@ AC_DEFUN([ACX_CHECK_SS_FAMILY],
|
||||
#endif
|
||||
]) ])
|
||||
|
||||
dnl Check if CC and linker support -fPIE and -pie.
|
||||
dnl If so, sets them in CFLAGS / LDFLAGS.
|
||||
AC_DEFUN([ACX_CHECK_PIE], [
|
||||
AC_ARG_ENABLE([pie], AS_HELP_STRING([--enable-pie], [Enable Position-Independent Executable (eg. to fully benefit from ASLR, small performance penalty)]))
|
||||
AS_IF([test "x$enable_pie" = "xyes"], [
|
||||
AC_MSG_CHECKING([if $CC supports PIE])
|
||||
BAKLDFLAGS="$LDFLAGS"
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
LDFLAGS="$LDFLAGS -pie"
|
||||
CFLAGS="$CFLAGS -fPIE"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then
|
||||
LDFLAGS="$BAKLDFLAGS"
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
rm -f conftest conftest.c conftest.o
|
||||
], [LDFLAGS="$BAKLDFLAGS" ; CFLAGS="$BAKCFLAGS" ; AC_MSG_RESULT(no)])
|
||||
])
|
||||
])
|
||||
|
||||
dnl Check if linker supports -Wl,-z,relro,-z,now.
|
||||
dnl If so, adds it to LDFLAGS.
|
||||
AC_DEFUN([ACX_CHECK_RELRO_NOW], [
|
||||
AC_ARG_ENABLE([relro_now], AS_HELP_STRING([--enable-relro-now], [Enable full relocation binding at load-time (RELRO NOW, to protect GOT and .dtor areas)]))
|
||||
AS_IF([test "x$enable_relro_now" = "xyes"], [
|
||||
AC_MSG_CHECKING([if $CC supports -Wl,-z,relro,-z,now])
|
||||
BAKLDFLAGS="$LDFLAGS"
|
||||
LDFLAGS="$LDFLAGS -Wl,-z,relro,-z,now"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [
|
||||
if $CC $CFLAGS $LDFLAGS -o conftest conftest.c 2>&1 | grep "warning: no debug symbols in executable" >/dev/null; then
|
||||
LDFLAGS="$BAKLDFLAGS"
|
||||
AC_MSG_RESULT(no)
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
fi
|
||||
rm -f conftest conftest.c conftest.o
|
||||
], [LDFLAGS="$BAKLDFLAGS" ; AC_MSG_RESULT(no)])
|
||||
])
|
||||
])
|
||||
|
||||
dnl End of file
|
||||
|
||||
+112
-80
@@ -9,83 +9,84 @@ 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
|
||||
|
||||
if test -z "$PYTHON_VERSION"; then
|
||||
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"
|
||||
PYTHON_VERSION=`$PYTHON -c "import sys, string; \
|
||||
print string.split(sys.version)[[0]]"`
|
||||
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 for a version of Python >= 2.1.0
|
||||
#
|
||||
AC_MSG_CHECKING([for a version of Python >= '2.1.0'])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver >= '2.1.0'"`
|
||||
if test "$ac_supports_python_ver" != "True"; then
|
||||
if test -z "$PYTHON_NOVERSIONCHECK"; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_FAILURE([
|
||||
This version of the AC@&t@_PYTHON_DEVEL macro
|
||||
doesn't work properly with versions of Python before
|
||||
2.1.0. You may need to re-run configure, setting the
|
||||
variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
|
||||
PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
|
||||
Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
|
||||
to something else than an empty string.
|
||||
])
|
||||
else
|
||||
AC_MSG_RESULT([skip at user request])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
sysconfig_module="$m"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
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
|
||||
#
|
||||
# if the macro parameter ``version'' is set, honour it
|
||||
#
|
||||
if test -n "$1"; then
|
||||
AC_MSG_CHECKING([for a version of Python $1])
|
||||
ac_supports_python_ver=`$PYTHON -c "import sys, string; \
|
||||
ver = string.split(sys.version)[[0]]; \
|
||||
print ver $1"`
|
||||
if test "$ac_supports_python_ver" = "True"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_ERROR([this package requires Python $1.
|
||||
If you have it installed, but it isn't the default Python
|
||||
interpreter in your system path, please pass the PYTHON_VERSION
|
||||
variable to configure. See ``configure --help'' for reference.
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
|
||||
if test -z "$ac_distutils_result"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
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,33 +100,64 @@ 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 *; \
|
||||
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
|
||||
# (makes two attempts to ensure we've got a version number
|
||||
# from the interpreter)
|
||||
py_version=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print join(get_config_vars('VERSION'))"`
|
||||
if test "$py_version" = "[None]"; then
|
||||
if test -n "$PYTHON_VERSION"; then
|
||||
py_version=$PYTHON_VERSION
|
||||
else
|
||||
py_version=`$PYTHON -c "import sys; \
|
||||
print sys.version[[:3]]"`
|
||||
fi
|
||||
fi
|
||||
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
from string import join; \
|
||||
print '-L' + get_python_lib(0,1), \
|
||||
'-L' + os.path.dirname(get_python_lib(0,1)), \
|
||||
'-lpython';"`$py_version
|
||||
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])
|
||||
|
||||
#
|
||||
# libraries which must be linked in when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra libraries)
|
||||
if test -z "$PYTHON_EXTRA_LIBS"; then
|
||||
PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LOCALMODLIBS'), conf('LIBS')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
|
||||
AC_SUBST(PYTHON_EXTRA_LIBS)
|
||||
|
||||
#
|
||||
# linking flags needed when embedding
|
||||
#
|
||||
AC_MSG_CHECKING(python extra linking flags)
|
||||
if test -z "$PYTHON_EXTRA_LDFLAGS"; then
|
||||
PYTHON_EXTRA_LDFLAGS=`$PYTHON -c "import distutils.sysconfig; \
|
||||
conf = distutils.sysconfig.get_config_var; \
|
||||
print conf('LINKFORSHARED')"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_EXTRA_LDFLAGS])
|
||||
AC_SUBST(PYTHON_EXTRA_LDFLAGS)
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
@@ -137,11 +169,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])
|
||||
|
||||
|
||||
+121
-326
@@ -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 31
|
||||
#serial 20
|
||||
|
||||
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_RESULT([$ax_pthread_ok])
|
||||
if test "x$ax_pthread_ok" = "xno"; then
|
||||
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
|
||||
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,163 +132,68 @@ 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?
|
||||
if test x"$ax_pthread_ok" = xno; then
|
||||
for flag in $ax_pthread_flags; do
|
||||
|
||||
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"
|
||||
|
||||
|
||||
# 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
|
||||
darwin* | hpux* | linux* | osf* | solaris*)
|
||||
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])
|
||||
AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
|
||||
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"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
@@ -312,18 +204,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);
|
||||
@@ -331,188 +213,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])
|
||||
AC_MSG_RESULT($ax_pthread_ok)
|
||||
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
|
||||
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])
|
||||
AC_SUBST(PTHREAD_LIBS)
|
||||
AC_SUBST(PTHREAD_CFLAGS)
|
||||
AC_SUBST(PTHREAD_CC)
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
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])
|
||||
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
|
||||
ax_pthread_ok=no
|
||||
|
||||
-1032
File diff suppressed because it is too large
Load Diff
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* cachedb/cachedb.h - cache from a database external to the program module
|
||||
*
|
||||
* Copyright (c) 2016, 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
|
||||
*
|
||||
* This file contains a module that uses an external database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
#include "util/module.h"
|
||||
struct cachedb_backend;
|
||||
struct module_stack;
|
||||
|
||||
/**
|
||||
* The global variable environment contents for the cachedb
|
||||
* Shared between threads, this represents long term information.
|
||||
* Like database connections.
|
||||
*/
|
||||
struct cachedb_env {
|
||||
/** true is cachedb is enabled, the backend is turned on */
|
||||
int enabled;
|
||||
|
||||
/** the backend routines */
|
||||
struct cachedb_backend* backend;
|
||||
|
||||
/** backend specific data here */
|
||||
void* backend_data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Per query state for the cachedb module.
|
||||
*/
|
||||
struct cachedb_qstate {
|
||||
int todo;
|
||||
};
|
||||
|
||||
/**
|
||||
* Backend call routines
|
||||
*/
|
||||
struct cachedb_backend {
|
||||
/** backend name */
|
||||
const char* name;
|
||||
|
||||
/** Init(env, cachedb_env): false on setup failure */
|
||||
int (*init)(struct module_env*, struct cachedb_env*);
|
||||
|
||||
/** Deinit - close db for program exit */
|
||||
void (*deinit)(struct module_env*, struct cachedb_env*);
|
||||
|
||||
/** Lookup (env, cachedb_env, key, result_buffer): true if found */
|
||||
int (*lookup)(struct module_env*, struct cachedb_env*, char*,
|
||||
struct sldns_buffer*);
|
||||
|
||||
/** Store (env, cachedb_env, key, data, data_len) */
|
||||
void (*store)(struct module_env*, struct cachedb_env*, char*,
|
||||
uint8_t*, size_t, time_t);
|
||||
};
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** Init the cachedb module */
|
||||
int cachedb_init(struct module_env* env, int id);
|
||||
/** Deinit the cachedb module */
|
||||
void cachedb_deinit(struct module_env* env, int id);
|
||||
/** Operate on an event on a query (in qstate). */
|
||||
void cachedb_operate(struct module_qstate* qstate, enum module_ev event,
|
||||
int id, struct outbound_entry* outbound);
|
||||
/** Subordinate query done, inform this super request of its conclusion */
|
||||
void cachedb_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
/** clear the cachedb query-specific contents out of qstate */
|
||||
void cachedb_clear(struct module_qstate* qstate, int id);
|
||||
/** return memory estimate for cachedb module */
|
||||
size_t cachedb_get_mem(struct module_env* env, int id);
|
||||
|
||||
/**
|
||||
* Get the function block with pointers to the cachedb functions
|
||||
* @return the function block for "cachedb".
|
||||
*/
|
||||
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);
|
||||
-376
@@ -1,376 +0,0 @@
|
||||
/*
|
||||
* cachedb/redis.c - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/redis.h"
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#ifdef USE_REDIS
|
||||
#include "hiredis/hiredis.h"
|
||||
|
||||
struct redis_moddata {
|
||||
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 */
|
||||
const char* server_path; /* server's unix path, or "", NULL if unused */
|
||||
const char* server_password; /* server's AUTH password, or "", NULL if unused */
|
||||
struct timeval timeout; /* timeout for connection setup and commands */
|
||||
int logical_db; /* the redis logical database to use */
|
||||
};
|
||||
|
||||
static redisReply* redis_command(struct module_env*, struct cachedb_env*,
|
||||
const char*, const uint8_t*, size_t);
|
||||
|
||||
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);
|
||||
}
|
||||
free(*moddata);
|
||||
*moddata = NULL;
|
||||
}
|
||||
|
||||
static redisContext*
|
||||
redis_connect(const struct redis_moddata* moddata)
|
||||
{
|
||||
redisContext* ctx;
|
||||
|
||||
if(moddata->server_path && moddata->server_path[0]!=0) {
|
||||
ctx = redisConnectUnixWithTimeout(moddata->server_path,
|
||||
moddata->timeout);
|
||||
} else {
|
||||
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 server: %s", errstr);
|
||||
goto fail;
|
||||
}
|
||||
if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
|
||||
log_err("failed to set redis timeout");
|
||||
goto fail;
|
||||
}
|
||||
if(moddata->server_password && moddata->server_password[0]!=0) {
|
||||
redisReply* rep;
|
||||
rep = redisCommand(ctx, "AUTH %s", moddata->server_password);
|
||||
if(!rep || rep->type == REDIS_REPLY_ERROR) {
|
||||
log_err("failed to authenticate with password");
|
||||
freeReplyObject(rep);
|
||||
goto fail;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
if(moddata->logical_db > 0) {
|
||||
redisReply* rep;
|
||||
rep = redisCommand(ctx, "SELECT %d", moddata->logical_db);
|
||||
if(!rep || rep->type == REDIS_REPLY_ERROR) {
|
||||
log_err("failed to set logical database (%d)",
|
||||
moddata->logical_db);
|
||||
freeReplyObject(rep);
|
||||
goto fail;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
verbose(VERB_OPS, "Connection to Redis established");
|
||||
return ctx;
|
||||
|
||||
fail:
|
||||
if(ctx)
|
||||
redisFree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
moddata = calloc(1, sizeof(struct redis_moddata));
|
||||
if(!moddata) {
|
||||
log_err("out of memory");
|
||||
goto fail;
|
||||
}
|
||||
moddata->numctxs = env->cfg->num_threads;
|
||||
moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
|
||||
if(!moddata->ctxs) {
|
||||
log_err("out of memory");
|
||||
goto fail;
|
||||
}
|
||||
/* 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->server_path = env->cfg->redis_server_path;
|
||||
moddata->server_password = env->cfg->redis_server_password;
|
||||
moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
|
||||
moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
|
||||
moddata->logical_db = env->cfg->redis_logical_db;
|
||||
for(i = 0; i < moddata->numctxs; i++) {
|
||||
redisContext* ctx = redis_connect(moddata);
|
||||
if(!ctx) {
|
||||
log_err("redis_init: failed to init redis");
|
||||
goto fail;
|
||||
}
|
||||
moddata->ctxs[i] = ctx;
|
||||
}
|
||||
cachedb_env->backend_data = moddata;
|
||||
if(env->cfg->redis_expire_records) {
|
||||
redisReply* rep = NULL;
|
||||
int redis_reply_type = 0;
|
||||
/** check if setex command is supported */
|
||||
rep = redis_command(env, cachedb_env,
|
||||
"SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0);
|
||||
if(!rep) {
|
||||
/** init failed, no response from redis server*/
|
||||
log_err("redis_init: failed to init redis, the "
|
||||
"redis-expire-records option requires the SETEX command "
|
||||
"(redis >= 2.0.0)");
|
||||
goto fail;
|
||||
}
|
||||
redis_reply_type = rep->type;
|
||||
freeReplyObject(rep);
|
||||
switch(redis_reply_type) {
|
||||
case REDIS_REPLY_STATUS:
|
||||
break;
|
||||
default:
|
||||
/** init failed, setex command not supported */
|
||||
log_err("redis_init: failed to init redis, the "
|
||||
"redis-expire-records option requires the SETEX command "
|
||||
"(redis >= 2.0.0)");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
moddata_clean(&moddata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct redis_moddata* moddata = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
|
||||
verbose(VERB_OPS, "Redis deinitialization");
|
||||
moddata_clean(&moddata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a redis command and get a reply. Unified so that it can be used for
|
||||
* both SET and GET. If 'data' is non-NULL the command is supposed to be
|
||||
* SET and GET otherwise, but the implementation of this function is agnostic
|
||||
* about the semantics (except for logging): 'command', 'data', and 'data_len'
|
||||
* are opaquely passed to redisCommand().
|
||||
* This function first checks whether a connection with a redis server has
|
||||
* been established; if not it tries to set up a new one.
|
||||
* It returns redisReply returned from redisCommand() or NULL if some low
|
||||
* level error happens. The caller is responsible to check the return value,
|
||||
* if it's non-NULL, it has to free it with freeReplyObject().
|
||||
*/
|
||||
static redisReply*
|
||||
redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
const char* command, const uint8_t* data, size_t data_len)
|
||||
{
|
||||
redisContext* ctx;
|
||||
redisReply* rep;
|
||||
struct redis_moddata* d = (struct redis_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
|
||||
/* We assume env->alloc->thread_num is a unique ID for each thread
|
||||
* in [0, num-of-threads). We could treat it as an error condition
|
||||
* if the assumption didn't hold, but it seems to be a fundamental
|
||||
* assumption throughout the unbound architecture, so we simply assert
|
||||
* it. */
|
||||
log_assert(env->alloc->thread_num < d->numctxs);
|
||||
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) {
|
||||
ctx = redis_connect(d);
|
||||
d->ctxs[env->alloc->thread_num] = ctx;
|
||||
}
|
||||
if(!ctx)
|
||||
return NULL;
|
||||
|
||||
/* Send the command and get a reply, synchronously. */
|
||||
rep = (redisReply*)redisCommand(ctx, command, data, data_len);
|
||||
if(!rep) {
|
||||
/* Once an error as a NULL-reply is returned the context cannot
|
||||
* be reused and we'll need to set up a new connection. */
|
||||
log_err("redis_command: failed to receive a reply, "
|
||||
"closing connection: %s", ctx->errstr);
|
||||
redisFree(ctx);
|
||||
d->ctxs[env->alloc->thread_num] = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Check error in reply to unify logging in that case.
|
||||
* The caller may perform context-dependent checks and logging. */
|
||||
if(rep->type == REDIS_REPLY_ERROR)
|
||||
log_err("redis: %s resulted in an error: %s",
|
||||
data ? "set" : "get", rep->str);
|
||||
|
||||
return rep;
|
||||
}
|
||||
|
||||
static int
|
||||
redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
redisReply* rep;
|
||||
char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
|
||||
int n;
|
||||
int ret = 0;
|
||||
|
||||
verbose(VERB_ALGO, "redis_lookup of %s", key);
|
||||
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
|
||||
if(n < 0 || n >= (int)sizeof(cmdbuf)) {
|
||||
log_err("redis_lookup: unexpected failure to build command");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
|
||||
if(!rep)
|
||||
return 0;
|
||||
switch(rep->type) {
|
||||
case REDIS_REPLY_NIL:
|
||||
verbose(VERB_ALGO, "redis_lookup: no data cached");
|
||||
break;
|
||||
case REDIS_REPLY_STRING:
|
||||
verbose(VERB_ALGO, "redis_lookup found %d bytes",
|
||||
(int)rep->len);
|
||||
if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
|
||||
log_err("redis_lookup: replied data too long: %lu",
|
||||
(size_t)rep->len);
|
||||
break;
|
||||
}
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, rep->str, rep->len);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
ret = 1;
|
||||
break;
|
||||
case REDIS_REPLY_ERROR:
|
||||
break; /* already logged */
|
||||
default:
|
||||
log_err("redis_lookup: unexpected type of reply for (%d)",
|
||||
rep->type);
|
||||
break;
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
redisReply* rep;
|
||||
int n;
|
||||
int set_ttl = (env->cfg->redis_expire_records &&
|
||||
(!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0));
|
||||
/* Supported commands:
|
||||
* - "SET " + key + " %b"
|
||||
* - "SETEX " + key + " " + ttl + " %b"
|
||||
*/
|
||||
char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1];
|
||||
|
||||
if (!set_ttl) {
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
|
||||
} else {
|
||||
/* add expired ttl time to redis ttl to avoid premature eviction of key */
|
||||
ttl += env->cfg->serve_expired_ttl;
|
||||
verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u",
|
||||
key, (int)data_len, (uint32_t)ttl);
|
||||
/* build command to set to a binary safe string */
|
||||
n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key,
|
||||
(uint32_t)ttl);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
if(rep) {
|
||||
verbose(VERB_ALGO, "redis_store set completed");
|
||||
if(rep->type != REDIS_REPLY_STATUS &&
|
||||
rep->type != REDIS_REPLY_ERROR) {
|
||||
log_err("redis_store: unexpected type of reply (%d)",
|
||||
rep->type);
|
||||
}
|
||||
freeReplyObject(rep);
|
||||
}
|
||||
}
|
||||
|
||||
struct cachedb_backend redis_backend = { "redis",
|
||||
redis_init, redis_deinit, redis_lookup, redis_store
|
||||
};
|
||||
#endif /* USE_REDIS */
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* cachedb/redis.h - cachedb redis module
|
||||
*
|
||||
* Copyright (c) 2018, 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
|
||||
*
|
||||
* This file contains a module that uses the redis database to cache
|
||||
* dns responses.
|
||||
*/
|
||||
|
||||
/** the redis backend definition, contains callable functions
|
||||
* and name string */
|
||||
extern struct cachedb_backend redis_backend;
|
||||
@@ -1,82 +0,0 @@
|
||||
/* arc4_lock.c - global lock for arc4random
|
||||
*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
#include "config.h"
|
||||
#define LOCKRET(func) func
|
||||
#ifdef ENABLE_LOCK_CHECKS
|
||||
#undef ENABLE_LOCK_CHECKS
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
|
||||
void _ARC4_LOCK(void);
|
||||
void _ARC4_UNLOCK(void);
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
void _ARC4_LOCK(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _ARC4_UNLOCK(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
}
|
||||
#else /* !THREADS_DISABLED */
|
||||
|
||||
static lock_quick_type arc4lock;
|
||||
static int arc4lockinit = 0;
|
||||
|
||||
void _ARC4_LOCK(void)
|
||||
{
|
||||
if(!arc4lockinit) {
|
||||
arc4lockinit = 1;
|
||||
lock_quick_init(&arc4lock);
|
||||
}
|
||||
lock_quick_lock(&arc4lock);
|
||||
}
|
||||
|
||||
void _ARC4_UNLOCK(void)
|
||||
{
|
||||
lock_quick_unlock(&arc4lock);
|
||||
}
|
||||
|
||||
void _ARC4_LOCK_DESTROY(void)
|
||||
{
|
||||
if(arc4lockinit) {
|
||||
arc4lockinit = 0;
|
||||
lock_quick_destroy(&arc4lock);
|
||||
}
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
@@ -1,312 +0,0 @@
|
||||
/* $OpenBSD: arc4random.c,v 1.41 2014/07/12 13:24:54 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996, David Mazieres <dm@uun.org>
|
||||
* Copyright (c) 2008, Damien Miller <djm@openbsd.org>
|
||||
* Copyright (c) 2013, Markus Friedl <markus@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.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* ChaCha based random number generator for OpenBSD.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#ifndef UB_ON_WINDOWS
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#define KEYSTREAM_ONLY
|
||||
#include "chacha_private.h"
|
||||
|
||||
#define arc4_min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#define KEYSZ 32
|
||||
#define IVSZ 8
|
||||
#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 */
|
||||
size_t rs_count; /* bytes till reseed */
|
||||
} *rs;
|
||||
|
||||
/* Preserved in fork children. */
|
||||
static struct {
|
||||
chacha_ctx rs_chacha; /* chacha context for random keystream */
|
||||
u_char rs_buf[RSBUFSZ]; /* keystream blocks */
|
||||
} *rsx;
|
||||
|
||||
static inline void _rs_rekey(u_char *dat, size_t datlen);
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
fallback_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;
|
||||
}
|
||||
|
||||
/* fallback for getentropy in case libc returns failure */
|
||||
static int
|
||||
fallback_getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
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
|
||||
# ifdef HAVE_FCNTL
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
#endif
|
||||
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 (fallback_gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
assert(buf);
|
||||
if (n < KEYSZ + IVSZ)
|
||||
return;
|
||||
|
||||
if (rs == NULL) {
|
||||
#ifndef UB_ON_WINDOWS
|
||||
if ((rs = mmap(NULL, sizeof(*rs), PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
|
||||
abort();
|
||||
#ifdef MAP_INHERIT_ZERO
|
||||
if (minherit(rs, sizeof(*rs), MAP_INHERIT_ZERO) == -1)
|
||||
abort();
|
||||
#endif
|
||||
#else /* WINDOWS */
|
||||
rs = malloc(sizeof(*rs));
|
||||
if(!rs)
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
if (rsx == NULL) {
|
||||
#ifndef UB_ON_WINDOWS
|
||||
if ((rsx = mmap(NULL, sizeof(*rsx), PROT_READ|PROT_WRITE,
|
||||
MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
|
||||
abort();
|
||||
#else /* WINDOWS */
|
||||
rsx = malloc(sizeof(*rsx));
|
||||
if(!rsx)
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8, 0);
|
||||
chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ);
|
||||
}
|
||||
|
||||
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
|
||||
raise(SIGKILL);
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!rs)
|
||||
_rs_init(rnd, sizeof(rnd));
|
||||
else
|
||||
_rs_rekey(rnd, sizeof(rnd));
|
||||
explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */
|
||||
|
||||
/* invalidate rs_buf */
|
||||
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);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_stir_if_needed(size_t len)
|
||||
{
|
||||
#ifndef MAP_INHERIT_ZERO
|
||||
static pid_t _rs_pid = 0;
|
||||
pid_t pid = getpid();
|
||||
|
||||
/* If a system lacks MAP_INHERIT_ZERO, resort to getpid() */
|
||||
if (_rs_pid == 0 || _rs_pid != pid) {
|
||||
_rs_pid = pid;
|
||||
if (rs)
|
||||
rs->rs_count = 0;
|
||||
}
|
||||
#endif
|
||||
if (!rs || rs->rs_count <= len)
|
||||
_rs_stir();
|
||||
if (rs->rs_count <= len)
|
||||
rs->rs_count = 0;
|
||||
else
|
||||
rs->rs_count -= len;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_rekey(u_char *dat, size_t datlen)
|
||||
{
|
||||
#ifndef KEYSTREAM_ONLY
|
||||
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
|
||||
#endif
|
||||
/* fill rs_buf with the keystream */
|
||||
chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf,
|
||||
rsx->rs_buf, sizeof(rsx->rs_buf));
|
||||
/* mix in optional user provided data */
|
||||
if (dat) {
|
||||
size_t i, m;
|
||||
|
||||
m = arc4_min(datlen, KEYSZ + IVSZ);
|
||||
for (i = 0; i < m; i++)
|
||||
rsx->rs_buf[i] ^= dat[i];
|
||||
}
|
||||
/* immediately reinit for backtracking resistance */
|
||||
_rs_init(rsx->rs_buf, KEYSZ + IVSZ);
|
||||
memset(rsx->rs_buf, 0, KEYSZ + IVSZ);
|
||||
rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_random_buf(void *_buf, size_t n)
|
||||
{
|
||||
u_char *buf = (u_char *)_buf;
|
||||
u_char *keystream;
|
||||
size_t m;
|
||||
|
||||
_rs_stir_if_needed(n);
|
||||
while (n > 0) {
|
||||
if (rs->rs_have > 0) {
|
||||
m = arc4_min(n, rs->rs_have);
|
||||
keystream = rsx->rs_buf + sizeof(rsx->rs_buf)
|
||||
- rs->rs_have;
|
||||
memcpy(buf, keystream, m);
|
||||
memset(keystream, 0, m);
|
||||
buf += m;
|
||||
n -= m;
|
||||
rs->rs_have -= m;
|
||||
}
|
||||
if (rs->rs_have == 0)
|
||||
_rs_rekey(NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_rs_random_u32(uint32_t *val)
|
||||
{
|
||||
u_char *keystream;
|
||||
_rs_stir_if_needed(sizeof(*val));
|
||||
if (rs->rs_have < sizeof(*val))
|
||||
_rs_rekey(NULL, 0);
|
||||
keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have;
|
||||
memcpy(val, keystream, sizeof(*val));
|
||||
memset(keystream, 0, sizeof(*val));
|
||||
rs->rs_have -= sizeof(*val);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
arc4random(void)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
_ARC4_LOCK();
|
||||
_rs_random_u32(&val);
|
||||
_ARC4_UNLOCK();
|
||||
return val;
|
||||
}
|
||||
|
||||
void
|
||||
arc4random_buf(void *buf, size_t n)
|
||||
{
|
||||
_ARC4_LOCK();
|
||||
_rs_random_buf(buf, n);
|
||||
_ARC4_UNLOCK();
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* $OpenBSD: arc4random_uniform.c,v 1.1 2014/07/12 13:24:54 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, Damien Miller <djm@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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Calculate a uniformly distributed random number less than upper_bound
|
||||
* avoiding "modulo bias".
|
||||
*
|
||||
* Uniformity is achieved by generating new random numbers until the one
|
||||
* returned is outside the range [0, 2**32 % upper_bound). This
|
||||
* guarantees the selected random number will be inside
|
||||
* [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound)
|
||||
* after reduction modulo upper_bound.
|
||||
*/
|
||||
uint32_t
|
||||
arc4random_uniform(uint32_t upper_bound)
|
||||
{
|
||||
uint32_t r, min;
|
||||
|
||||
if (upper_bound < 2)
|
||||
return 0;
|
||||
|
||||
/* 2**32 % x == (2**32 - x) % x */
|
||||
min = -upper_bound % upper_bound;
|
||||
|
||||
/*
|
||||
* This could theoretically loop forever but each retry has
|
||||
* p > 0.5 (worst case, usually far better) of selecting a
|
||||
* number inside the range we need, so it should rarely need
|
||||
* to re-roll.
|
||||
*/
|
||||
for (;;) {
|
||||
r = arc4random();
|
||||
if (r >= min)
|
||||
break;
|
||||
}
|
||||
|
||||
return r % upper_bound;
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
/*
|
||||
chacha-merged.c version 20080118
|
||||
D. J. Bernstein
|
||||
Public domain.
|
||||
*/
|
||||
|
||||
/* $OpenBSD: chacha_private.h,v 1.2 2013/10/04 07:02:27 djm Exp $ */
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned int u32;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 input[16]; /* could be compressed */
|
||||
} chacha_ctx;
|
||||
|
||||
#define U8C(v) (v##U)
|
||||
#define U32C(v) (v##U)
|
||||
|
||||
#define U8V(v) ((u8)(v) & U8C(0xFF))
|
||||
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
|
||||
|
||||
#define ROTL32(v, n) \
|
||||
(U32V((v) << (n)) | ((v) >> (32 - (n))))
|
||||
|
||||
#define U8TO32_LITTLE(p) \
|
||||
(((u32)((p)[0]) ) | \
|
||||
((u32)((p)[1]) << 8) | \
|
||||
((u32)((p)[2]) << 16) | \
|
||||
((u32)((p)[3]) << 24))
|
||||
|
||||
#define U32TO8_LITTLE(p, v) \
|
||||
do { \
|
||||
(p)[0] = U8V((v) ); \
|
||||
(p)[1] = U8V((v) >> 8); \
|
||||
(p)[2] = U8V((v) >> 16); \
|
||||
(p)[3] = U8V((v) >> 24); \
|
||||
} while (0)
|
||||
|
||||
#define ROTATE(v,c) (ROTL32(v,c))
|
||||
#define XOR(v,w) ((v) ^ (w))
|
||||
#define PLUS(v,w) (U32V((v) + (w)))
|
||||
#define PLUSONE(v) (PLUS((v),1))
|
||||
|
||||
#define QUARTERROUND(a,b,c,d) \
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
|
||||
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))
|
||||
{
|
||||
const char *constants;
|
||||
|
||||
x->input[4] = U8TO32_LITTLE(k + 0);
|
||||
x->input[5] = U8TO32_LITTLE(k + 4);
|
||||
x->input[6] = U8TO32_LITTLE(k + 8);
|
||||
x->input[7] = U8TO32_LITTLE(k + 12);
|
||||
if (kbits == 256) { /* recommended */
|
||||
k += 16;
|
||||
constants = sigma;
|
||||
} else { /* kbits == 128 */
|
||||
constants = tau;
|
||||
}
|
||||
x->input[8] = U8TO32_LITTLE(k + 0);
|
||||
x->input[9] = U8TO32_LITTLE(k + 4);
|
||||
x->input[10] = U8TO32_LITTLE(k + 8);
|
||||
x->input[11] = U8TO32_LITTLE(k + 12);
|
||||
x->input[0] = U8TO32_LITTLE(constants + 0);
|
||||
x->input[1] = U8TO32_LITTLE(constants + 4);
|
||||
x->input[2] = U8TO32_LITTLE(constants + 8);
|
||||
x->input[3] = U8TO32_LITTLE(constants + 12);
|
||||
}
|
||||
|
||||
static void
|
||||
chacha_ivsetup(chacha_ctx *x,const u8 *iv)
|
||||
{
|
||||
x->input[12] = 0;
|
||||
x->input[13] = 0;
|
||||
x->input[14] = U8TO32_LITTLE(iv + 0);
|
||||
x->input[15] = U8TO32_LITTLE(iv + 4);
|
||||
}
|
||||
|
||||
static void
|
||||
chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes)
|
||||
{
|
||||
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
|
||||
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
|
||||
u8 *ctarget = NULL;
|
||||
u8 tmp[64];
|
||||
u_int i;
|
||||
|
||||
if (!bytes) return;
|
||||
|
||||
j0 = x->input[0];
|
||||
j1 = x->input[1];
|
||||
j2 = x->input[2];
|
||||
j3 = x->input[3];
|
||||
j4 = x->input[4];
|
||||
j5 = x->input[5];
|
||||
j6 = x->input[6];
|
||||
j7 = x->input[7];
|
||||
j8 = x->input[8];
|
||||
j9 = x->input[9];
|
||||
j10 = x->input[10];
|
||||
j11 = x->input[11];
|
||||
j12 = x->input[12];
|
||||
j13 = x->input[13];
|
||||
j14 = x->input[14];
|
||||
j15 = x->input[15];
|
||||
|
||||
for (;;) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) tmp[i] = m[i];
|
||||
m = tmp;
|
||||
ctarget = c;
|
||||
c = tmp;
|
||||
}
|
||||
x0 = j0;
|
||||
x1 = j1;
|
||||
x2 = j2;
|
||||
x3 = j3;
|
||||
x4 = j4;
|
||||
x5 = j5;
|
||||
x6 = j6;
|
||||
x7 = j7;
|
||||
x8 = j8;
|
||||
x9 = j9;
|
||||
x10 = j10;
|
||||
x11 = j11;
|
||||
x12 = j12;
|
||||
x13 = j13;
|
||||
x14 = j14;
|
||||
x15 = j15;
|
||||
for (i = 20;i > 0;i -= 2) {
|
||||
QUARTERROUND( x0, x4, x8,x12)
|
||||
QUARTERROUND( x1, x5, x9,x13)
|
||||
QUARTERROUND( x2, x6,x10,x14)
|
||||
QUARTERROUND( x3, x7,x11,x15)
|
||||
QUARTERROUND( x0, x5,x10,x15)
|
||||
QUARTERROUND( x1, x6,x11,x12)
|
||||
QUARTERROUND( x2, x7, x8,x13)
|
||||
QUARTERROUND( x3, x4, x9,x14)
|
||||
}
|
||||
x0 = PLUS(x0,j0);
|
||||
x1 = PLUS(x1,j1);
|
||||
x2 = PLUS(x2,j2);
|
||||
x3 = PLUS(x3,j3);
|
||||
x4 = PLUS(x4,j4);
|
||||
x5 = PLUS(x5,j5);
|
||||
x6 = PLUS(x6,j6);
|
||||
x7 = PLUS(x7,j7);
|
||||
x8 = PLUS(x8,j8);
|
||||
x9 = PLUS(x9,j9);
|
||||
x10 = PLUS(x10,j10);
|
||||
x11 = PLUS(x11,j11);
|
||||
x12 = PLUS(x12,j12);
|
||||
x13 = PLUS(x13,j13);
|
||||
x14 = PLUS(x14,j14);
|
||||
x15 = PLUS(x15,j15);
|
||||
|
||||
#ifndef KEYSTREAM_ONLY
|
||||
x0 = XOR(x0,U8TO32_LITTLE(m + 0));
|
||||
x1 = XOR(x1,U8TO32_LITTLE(m + 4));
|
||||
x2 = XOR(x2,U8TO32_LITTLE(m + 8));
|
||||
x3 = XOR(x3,U8TO32_LITTLE(m + 12));
|
||||
x4 = XOR(x4,U8TO32_LITTLE(m + 16));
|
||||
x5 = XOR(x5,U8TO32_LITTLE(m + 20));
|
||||
x6 = XOR(x6,U8TO32_LITTLE(m + 24));
|
||||
x7 = XOR(x7,U8TO32_LITTLE(m + 28));
|
||||
x8 = XOR(x8,U8TO32_LITTLE(m + 32));
|
||||
x9 = XOR(x9,U8TO32_LITTLE(m + 36));
|
||||
x10 = XOR(x10,U8TO32_LITTLE(m + 40));
|
||||
x11 = XOR(x11,U8TO32_LITTLE(m + 44));
|
||||
x12 = XOR(x12,U8TO32_LITTLE(m + 48));
|
||||
x13 = XOR(x13,U8TO32_LITTLE(m + 52));
|
||||
x14 = XOR(x14,U8TO32_LITTLE(m + 56));
|
||||
x15 = XOR(x15,U8TO32_LITTLE(m + 60));
|
||||
#endif
|
||||
|
||||
j12 = PLUSONE(j12);
|
||||
if (!j12) {
|
||||
j13 = PLUSONE(j13);
|
||||
/* stopping at 2^70 bytes per nonce is user's responsibility */
|
||||
}
|
||||
|
||||
U32TO8_LITTLE(c + 0,x0);
|
||||
U32TO8_LITTLE(c + 4,x1);
|
||||
U32TO8_LITTLE(c + 8,x2);
|
||||
U32TO8_LITTLE(c + 12,x3);
|
||||
U32TO8_LITTLE(c + 16,x4);
|
||||
U32TO8_LITTLE(c + 20,x5);
|
||||
U32TO8_LITTLE(c + 24,x6);
|
||||
U32TO8_LITTLE(c + 28,x7);
|
||||
U32TO8_LITTLE(c + 32,x8);
|
||||
U32TO8_LITTLE(c + 36,x9);
|
||||
U32TO8_LITTLE(c + 40,x10);
|
||||
U32TO8_LITTLE(c + 44,x11);
|
||||
U32TO8_LITTLE(c + 48,x12);
|
||||
U32TO8_LITTLE(c + 52,x13);
|
||||
U32TO8_LITTLE(c + 56,x14);
|
||||
U32TO8_LITTLE(c + 60,x15);
|
||||
|
||||
if (bytes <= 64) {
|
||||
if (bytes < 64) {
|
||||
for (i = 0;i < bytes;++i) ctarget[i] = c[i];
|
||||
}
|
||||
x->input[12] = j12;
|
||||
x->input[13] = j13;
|
||||
return;
|
||||
}
|
||||
bytes -= 64;
|
||||
c += 64;
|
||||
#ifndef KEYSTREAM_ONLY
|
||||
m += 64;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@
|
||||
#include "util/locks.h"
|
||||
|
||||
/** the lock for ctime buffer */
|
||||
static lock_basic_type ctime_lock;
|
||||
static lock_basic_t ctime_lock;
|
||||
/** has it been inited */
|
||||
static int ctime_r_init = 0;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/* $OpenBSD: explicit_bzero.c,v 1.3 2014/06/21 02:34:26 matthew Exp $ */
|
||||
/*
|
||||
* Public domain.
|
||||
* Written by Matthew Dempsky.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef HAVE_ATTR_WEAK
|
||||
__attribute__((weak)) void
|
||||
#else
|
||||
void
|
||||
#endif
|
||||
__explicit_bzero_hook(void *ATTR_UNUSED(buf), size_t ATTR_UNUSED(len))
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
explicit_bzero(void *buf, size_t len)
|
||||
{
|
||||
#ifdef UB_ON_WINDOWS
|
||||
SecureZeroMemory(buf, len);
|
||||
#endif
|
||||
memset(buf, 0, len);
|
||||
__explicit_bzero_hook(buf, len);
|
||||
}
|
||||
@@ -120,10 +120,12 @@ addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
|
||||
{
|
||||
struct addrinfo *ai;
|
||||
|
||||
ai = calloc(1, sizeof(*ai) + sizeof(struct sockaddr_in));
|
||||
ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
|
||||
if (ai == NULL)
|
||||
return (NULL);
|
||||
|
||||
memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
|
||||
|
||||
ai->ai_addr = (struct sockaddr *)(ai + 1);
|
||||
/* XXX -- ssh doesn't use sa_len */
|
||||
ai->ai_addrlen = sizeof(struct sockaddr_in);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1,539 +0,0 @@
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
* Copyright (c) 2014 Bob Beck <beck@obtuse.com>
|
||||
*
|
||||
* 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 "config.h"
|
||||
/*
|
||||
#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>
|
||||
#include <sys/syscall.h>
|
||||
#ifdef SYS__sysctl
|
||||
#include <linux/sysctl.h>
|
||||
#endif
|
||||
#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 <link.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#ifndef HAVE_NETTLE
|
||||
#include <openssl/sha.h>
|
||||
#else
|
||||
#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
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#include <sys/vfs.h>
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#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);
|
||||
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
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
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
#ifdef SYS__sysctl
|
||||
/*
|
||||
* Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID.
|
||||
* sysctl is a failsafe API, so it guarantees a result. This
|
||||
* should work inside a chroot, or when file descriptors are
|
||||
* exhausted.
|
||||
*
|
||||
* However this can fail if the Linux kernel removes support
|
||||
* for sysctl. Starting in 2007, there have been efforts to
|
||||
* deprecate the sysctl API/ABI, and push callers towards use
|
||||
* of the chroot-unavailable fd-using /proc mechanism --
|
||||
* essentially the same problems as /dev/urandom.
|
||||
*
|
||||
* Numerous setbacks have been encountered in their deprecation
|
||||
* schedule, so as of June 2014 the kernel ABI still exists on
|
||||
* most Linux architectures. The sysctl() stub in libc is missing
|
||||
* on some systems. There are also reports that some kernels
|
||||
* spew messages to the console.
|
||||
*/
|
||||
ret = getentropy_sysctl(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
/*
|
||||
* Entropy collection via /dev/urandom and sysctl have failed.
|
||||
*
|
||||
* No other API exists for collecting entropy. See the large
|
||||
* comment block above.
|
||||
*
|
||||
* 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 Linux
|
||||
* still 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.
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
int pre_errno = errno;
|
||||
int ret;
|
||||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret != (int)len)
|
||||
return (-1);
|
||||
errno = pre_errno;
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
struct stat st;
|
||||
size_t i;
|
||||
int fd, cnt, 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;
|
||||
}
|
||||
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
|
||||
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);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifdef SYS__sysctl
|
||||
static int
|
||||
getentropy_sysctl(void *buf, size_t len)
|
||||
{
|
||||
static int mib[] = { CTL_KERN, KERN_RANDOM, RANDOM_UUID };
|
||||
size_t i;
|
||||
int save_errno = errno;
|
||||
|
||||
for (i = 0; i < len; ) {
|
||||
size_t chunk = min(len - i, 16);
|
||||
|
||||
/* SYS__sysctl because some systems already removed sysctl() */
|
||||
struct __sysctl_args args = {
|
||||
.name = mib,
|
||||
.nlen = 3,
|
||||
.oldval = (char *)buf + i,
|
||||
.oldlenp = &chunk,
|
||||
};
|
||||
if (syscall(SYS__sysctl, &args) != 0)
|
||||
goto sysctlfailed;
|
||||
i += chunk;
|
||||
}
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
sysctlfailed:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
static const int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC,
|
||||
#endif
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
CLOCK_MONOTONIC_RAW,
|
||||
#endif
|
||||
#ifdef CLOCK_TAI
|
||||
CLOCK_TAI,
|
||||
#endif
|
||||
#ifdef CLOCK_VIRTUAL
|
||||
CLOCK_VIRTUAL,
|
||||
#endif
|
||||
#ifdef CLOCK_UPTIME
|
||||
CLOCK_UPTIME,
|
||||
#endif
|
||||
#ifdef CLOCK_PROCESS_CPUTIME_ID
|
||||
CLOCK_PROCESS_CPUTIME_ID,
|
||||
#endif
|
||||
#ifdef CLOCK_THREAD_CPUTIME_ID
|
||||
CLOCK_THREAD_CPUTIME_ID,
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
dl_iterate_phdr(getentropy_phdr, &ctx);
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
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);
|
||||
|
||||
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... */
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
|
||||
ii++) {
|
||||
HX((e = clock_gettime(cl[ii],
|
||||
&ts)) == -1, ts);
|
||||
if (e != -1)
|
||||
cnt += (int)ts.tv_nsec;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#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
|
||||
p = (char *) getauxval(AT_SYSINFO_EHDR);
|
||||
if (p)
|
||||
HR(p, pgs);
|
||||
#endif
|
||||
#ifdef AT_BASE
|
||||
p = (char *) getauxval(AT_BASE);
|
||||
if (p)
|
||||
HD(p);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
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 */
|
||||
}
|
||||
@@ -1,417 +0,0 @@
|
||||
/* $OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
* Copyright (c) 2014 Bob Beck <beck@obtuse.com>
|
||||
*
|
||||
* 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 <TargetConditionals.h>
|
||||
#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 <unistd.h>
|
||||
#include <time.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach/mach_host.h>
|
||||
#include <mach/host_info.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#endif
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#if TARGET_OS_OSX
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#endif
|
||||
#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);
|
||||
|
||||
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) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
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);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
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 };
|
||||
#endif
|
||||
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;
|
||||
#if TARGET_OS_OSX
|
||||
struct tcpstat tcpstat;
|
||||
struct udpstat udpstat;
|
||||
struct ipstat ipstat;
|
||||
#endif
|
||||
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);
|
||||
|
||||
#if TARGET_OS_OSX
|
||||
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);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
explicit_bzero(&ctx, sizeof ctx);
|
||||
explicit_bzero(results, sizeof results);
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
|
||||
* Copyright (c) 2014 Bob Beck <beck@obtuse.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/syscall.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>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_SYS_SHA2_H
|
||||
#include <sys/sha2.h>
|
||||
#define SHA512_Init SHA512Init
|
||||
#define SHA512_Update SHA512Update
|
||||
#define SHA512_Final SHA512Final
|
||||
#else
|
||||
#include <openssl/sha.h>
|
||||
#endif
|
||||
|
||||
#include <sys/vfs.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/loadavg.h>
|
||||
|
||||
#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, const char *path,
|
||||
int devfscheck);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to get entropy with /dev/urandom
|
||||
*
|
||||
* Solaris provides /dev/urandom as a symbolic link to
|
||||
* /devices/pseudo/random@0:urandom which is provided by
|
||||
* a devfs filesystem. Best practice is to use O_NOFOLLOW,
|
||||
* so we must try the unpublished name directly.
|
||||
*
|
||||
* This can fail if the process is inside a chroot which lacks
|
||||
* the devfs mount, or if file descriptors are exhausted.
|
||||
*/
|
||||
ret = getentropy_urandom(buf, len,
|
||||
"/devices/pseudo/random@0:urandom", 1);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Unfortunately, chroot spaces on Solaris are sometimes setup
|
||||
* with direct device node of the well-known /dev/urandom name
|
||||
* (perhaps to avoid dragging all of devfs into the space).
|
||||
*
|
||||
* This can fail if the process is inside a chroot or if file
|
||||
* descriptors are exhausted.
|
||||
*/
|
||||
ret = getentropy_urandom(buf, len, "/dev/urandom", 0);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* Entropy collection via /dev/urandom has failed.
|
||||
*
|
||||
* No other API exists for collecting entropy, and we have
|
||||
* no failsafe way to get it on Solaris 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 Solaris
|
||||
* does not provide a failsafe API for entropy collection.
|
||||
*
|
||||
* We hope this demonstrates that Solaris 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, const char *path, int devfscheck)
|
||||
{
|
||||
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(path, 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) ||
|
||||
(devfscheck && (strcmp(st.st_fstype, "devfs") != 0))) {
|
||||
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 const int cl[] = {
|
||||
CLOCK_REALTIME,
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
CLOCK_MONOTONIC,
|
||||
#endif
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
CLOCK_MONOTONIC_RAW,
|
||||
#endif
|
||||
#ifdef CLOCK_TAI
|
||||
CLOCK_TAI,
|
||||
#endif
|
||||
#ifdef CLOCK_VIRTUAL
|
||||
CLOCK_VIRTUAL,
|
||||
#endif
|
||||
#ifdef CLOCK_UPTIME
|
||||
CLOCK_UPTIME,
|
||||
#endif
|
||||
#ifdef CLOCK_PROCESS_CPUTIME_ID
|
||||
CLOCK_PROCESS_CPUTIME_ID,
|
||||
#endif
|
||||
#ifdef CLOCK_THREAD_CPUTIME_ID
|
||||
CLOCK_THREAD_CPUTIME_ID,
|
||||
#endif
|
||||
};
|
||||
|
||||
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;
|
||||
double loadavg[3];
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
|
||||
HX(clock_gettime(cl[ii], &ts) == -1, ts);
|
||||
|
||||
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);
|
||||
HX((getloadavg(loadavg, 3) == -1), loadavg);
|
||||
|
||||
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;
|
||||
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... */
|
||||
for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]);
|
||||
ii++) {
|
||||
HX((e = clock_gettime(cl[ii],
|
||||
&ts)) == -1, ts);
|
||||
if (e != -1)
|
||||
cnt += (int)ts.tv_nsec;
|
||||
}
|
||||
|
||||
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(stat("/", &st) == -1, st);
|
||||
HX(statvfs("/", &stvfs) == -1, stvfs);
|
||||
|
||||
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((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;
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
|
||||
* Copyright (c) 2014, Bob Beck <beck@obtuse.com>
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <wincrypt.h>
|
||||
#include <process.h>
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
/*
|
||||
* On Windows, CryptGenRandom is supposed to be a well-seeded
|
||||
* cryptographically strong random number generator.
|
||||
*/
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
HCRYPTPROV provider;
|
||||
|
||||
if (len > 256) {
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT) == 0)
|
||||
goto fail;
|
||||
if (CryptGenRandom(provider, len, buf) == 0) {
|
||||
CryptReleaseContext(provider, 0);
|
||||
goto fail;
|
||||
}
|
||||
CryptReleaseContext(provider, 0);
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
errno = EIO;
|
||||
return (-1);
|
||||
}
|
||||
+5
-5
@@ -103,7 +103,7 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if (!isdigit((unsigned char)c))
|
||||
if (!isdigit(c))
|
||||
return (0);
|
||||
val = 0; base = 10;
|
||||
if (c == '0') {
|
||||
@@ -114,12 +114,12 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
base = 8;
|
||||
}
|
||||
for (;;) {
|
||||
if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
|
||||
if (isascii(c) && isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
c = *++cp;
|
||||
} else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
|
||||
} else if (base == 16 && isascii(c) && isxdigit(c)) {
|
||||
val = (val << 4) |
|
||||
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
@@ -141,7 +141,7 @@ inet_aton(const char *cp, struct in_addr *addr)
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
|
||||
if (c != '\0' && (!isascii(c) || !isspace(c)))
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/* isblank - compatibility implementation of isblank
|
||||
*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/* return true for a blank character: space or tab */
|
||||
int isblank(int c);
|
||||
|
||||
/* implementation of isblank. unsigned char is the argument */
|
||||
int
|
||||
isblank(int c)
|
||||
{
|
||||
return (c==' ' || c=='\t');
|
||||
}
|
||||
@@ -5,12 +5,7 @@
|
||||
#undef malloc
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef USE_WINSOCK
|
||||
void *malloc ();
|
||||
#else
|
||||
/* provide a prototype */
|
||||
void *malloc (size_t n);
|
||||
#endif
|
||||
|
||||
/* Allocate an N-byte block of memory from the heap.
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ void *memmove(void *dest, const void *src, size_t n)
|
||||
to[i] = from[i];
|
||||
return dest;
|
||||
}
|
||||
if (from > to && from-to < (int)n) {
|
||||
if (from > to && from-to < (int)n) {
|
||||
/* to overlaps with from */
|
||||
/* <from......> */
|
||||
/* <to........> */
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/* $OpenBSD: reallocarray.c,v 1.1 2014/05/08 21:43:49 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
||||
-477
@@ -1,477 +0,0 @@
|
||||
/*
|
||||
* FILE: sha2.c
|
||||
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by Jelte Jansen to fit in ldns, and not clash with any
|
||||
* system-defined SHA code.
|
||||
* Changes:
|
||||
* - Renamed (external) functions and constants to fit ldns style
|
||||
* - Removed _End and _Data functions
|
||||
* - Added ldns_shaX(data, len, digest) convenience functions
|
||||
* - Removed prototypes of _Transform functions and made those static
|
||||
* Modified by Wouter, and trimmed, to provide SHA512 for getentropy_fallback.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 AUTHOR OR CONTRIBUTOR(S) 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.
|
||||
*
|
||||
* $Id: sha2.c,v 1.1 2001/11/08 00:01:51 adg Exp adg $
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h> /* memcpy()/memset() or bcopy()/bzero() */
|
||||
#include <assert.h> /* assert() */
|
||||
|
||||
/* do we have sha512 header defs */
|
||||
#ifndef SHA512_DIGEST_LENGTH
|
||||
#define SHA512_BLOCK_LENGTH 128
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
|
||||
typedef struct _SHA512_CTX {
|
||||
uint64_t state[8];
|
||||
uint64_t bitcount[2];
|
||||
uint8_t buffer[SHA512_BLOCK_LENGTH];
|
||||
} SHA512_CTX;
|
||||
#endif /* do we have sha512 header defs */
|
||||
|
||||
void SHA512_Init(SHA512_CTX*);
|
||||
void SHA512_Update(SHA512_CTX*, void*, size_t);
|
||||
void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
|
||||
unsigned char *SHA512(void *data, unsigned int data_len, unsigned char *digest);
|
||||
|
||||
|
||||
/*** SHA-256/384/512 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivalent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#error Define BYTE_ORDER to be equal to either LITTLE_ENDIAN or BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
typedef uint8_t sha2_byte; /* Exactly 1 byte */
|
||||
typedef uint32_t sha2_word32; /* Exactly 4 bytes */
|
||||
#ifdef S_SPLINT_S
|
||||
typedef unsigned long long sha2_word64; /* lint 8 bytes */
|
||||
#else
|
||||
typedef uint64_t sha2_word64; /* Exactly 8 bytes */
|
||||
#endif
|
||||
|
||||
/*** SHA-256/384/512 Various Length Definitions ***********************/
|
||||
#define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16)
|
||||
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_word32 tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
#ifndef S_SPLINT_S
|
||||
#define REVERSE64(w,x) { \
|
||||
sha2_word64 tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#else /* splint */
|
||||
#define REVERSE64(w,x) /* splint */
|
||||
#endif /* splint */
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
* unsigned 128-bit integer (represented using a two-element array of
|
||||
* 64-bit words):
|
||||
*/
|
||||
#define ADDINC128(w,n) { \
|
||||
(w)[0] += (sha2_word64)(n); \
|
||||
if ((w)[0] < (n)) { \
|
||||
(w)[1]++; \
|
||||
} \
|
||||
}
|
||||
#ifdef S_SPLINT_S
|
||||
#undef ADDINC128
|
||||
#define ADDINC128(w,n) /* splint */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros for copying blocks of memory and for zeroing out ranges
|
||||
* of memory. Using these macros makes it easy to switch from
|
||||
* using memset()/memcpy() and using bzero()/bcopy().
|
||||
*
|
||||
* Please define either SHA2_USE_MEMSET_MEMCPY or define
|
||||
* SHA2_USE_BZERO_BCOPY depending on which function set you
|
||||
* choose to use:
|
||||
*/
|
||||
#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Default to memset()/memcpy() if no option is specified */
|
||||
#define SHA2_USE_MEMSET_MEMCPY 1
|
||||
#endif
|
||||
#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Abort with an error if BOTH options are defined */
|
||||
#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
|
||||
#endif
|
||||
|
||||
#ifdef SHA2_USE_MEMSET_MEMCPY
|
||||
#define MEMSET_BZERO(p,l) memset((p), 0, (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
|
||||
#endif
|
||||
#ifdef SHA2_USE_BZERO_BCOPY
|
||||
#define MEMSET_BZERO(p,l) bzero((p), (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
|
||||
#endif
|
||||
|
||||
|
||||
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
|
||||
/*
|
||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||
*
|
||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||
* S is a ROTATION) because the SHA-256/384/512 description document
|
||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||
* same "backwards" definition.
|
||||
*/
|
||||
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
||||
#define R(b,x) ((x) >> (b))
|
||||
/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
|
||||
#define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b))))
|
||||
|
||||
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
/* Four of six logical functions used in SHA-384 and SHA-512: */
|
||||
#define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x)))
|
||||
#define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x)))
|
||||
#define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x)))
|
||||
#define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x)))
|
||||
|
||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||
/* Hash constant words K for SHA-384 and SHA-512: */
|
||||
static const sha2_word64 K512[80] = {
|
||||
0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL,
|
||||
0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
|
||||
0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
|
||||
0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
|
||||
0xd807aa98a3030242ULL, 0x12835b0145706fbeULL,
|
||||
0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
|
||||
0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL,
|
||||
0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
|
||||
0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
|
||||
0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
|
||||
0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL,
|
||||
0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
|
||||
0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL,
|
||||
0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
|
||||
0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
|
||||
0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
|
||||
0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL,
|
||||
0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
|
||||
0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL,
|
||||
0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
|
||||
0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
|
||||
0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
|
||||
0xd192e819d6ef5218ULL, 0xd69906245565a910ULL,
|
||||
0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
|
||||
0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL,
|
||||
0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
|
||||
0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
|
||||
0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
|
||||
0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL,
|
||||
0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
|
||||
0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL,
|
||||
0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
|
||||
0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
|
||||
0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
|
||||
0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL,
|
||||
0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
|
||||
0x28db77f523047d84ULL, 0x32caab7b40c72493ULL,
|
||||
0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
|
||||
0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
|
||||
0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
|
||||
};
|
||||
|
||||
/* initial hash value H for SHA-512 */
|
||||
static const sha2_word64 sha512_initial_hash_value[8] = {
|
||||
0x6a09e667f3bcc908ULL,
|
||||
0xbb67ae8584caa73bULL,
|
||||
0x3c6ef372fe94f82bULL,
|
||||
0xa54ff53a5f1d36f1ULL,
|
||||
0x510e527fade682d1ULL,
|
||||
0x9b05688c2b3e6c1fULL,
|
||||
0x1f83d9abfb41bd6bULL,
|
||||
0x5be0cd19137e2179ULL
|
||||
};
|
||||
|
||||
typedef union _ldns_sha2_buffer_union {
|
||||
uint8_t* theChars;
|
||||
uint64_t* theLongs;
|
||||
} ldns_sha2_buffer_union;
|
||||
|
||||
/*** SHA-512: *********************************************************/
|
||||
void SHA512_Init(SHA512_CTX* context) {
|
||||
if (context == (SHA512_CTX*)0) {
|
||||
return;
|
||||
}
|
||||
MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH);
|
||||
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH);
|
||||
context->bitcount[0] = context->bitcount[1] = 0;
|
||||
}
|
||||
|
||||
static void SHA512_Transform(SHA512_CTX* context,
|
||||
const sha2_word64* data) {
|
||||
sha2_word64 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer;
|
||||
int j;
|
||||
|
||||
/* initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert TO host byte order */
|
||||
REVERSE64(*data++, W512[j]);
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
/* Apply the SHA-512 compression function to update a..h with copy */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W512[(j+1)&0x0f];
|
||||
s0 = sigma0_512(s0);
|
||||
s1 = W512[(j+14)&0x0f];
|
||||
s1 = sigma1_512(s1);
|
||||
|
||||
/* Apply the SHA-512 compression function to update a..h */
|
||||
T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
|
||||
(W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_512(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 80);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
void SHA512_Update(SHA512_CTX* context, void *datain, size_t len) {
|
||||
size_t freespace, usedspace;
|
||||
const sha2_byte* data = (const sha2_byte*)datain;
|
||||
|
||||
if (len == 0) {
|
||||
/* Calling with no data is valid - we do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0);
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA512_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
|
||||
ADDINC128(context->bitcount, freespace << 3);
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA512_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA512_Transform(context, (sha2_word64*)data);
|
||||
ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3);
|
||||
len -= SHA512_BLOCK_LENGTH;
|
||||
data += SHA512_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
MEMCPY_BCOPY(context->buffer, data, len);
|
||||
ADDINC128(context->bitcount, len << 3);
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
static void SHA512_Last(SHA512_CTX* context) {
|
||||
size_t usedspace;
|
||||
ldns_sha2_buffer_union cast_var;
|
||||
|
||||
usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert FROM host byte order */
|
||||
REVERSE64(context->bitcount[0],context->bitcount[0]);
|
||||
REVERSE64(context->bitcount[1],context->bitcount[1]);
|
||||
#endif
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA512_BLOCK_LENGTH) {
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2);
|
||||
}
|
||||
} else {
|
||||
/* Prepare for final transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Store the length of input data (in bits): */
|
||||
cast_var.theChars = context->buffer;
|
||||
cast_var.theLongs[SHA512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1];
|
||||
cast_var.theLongs[SHA512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0];
|
||||
|
||||
/* final transform: */
|
||||
SHA512_Transform(context, (sha2_word64*)context->buffer);
|
||||
}
|
||||
|
||||
void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) {
|
||||
sha2_word64 *d = (sha2_word64*)digest;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (SHA512_CTX*)0);
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_byte*)0) {
|
||||
SHA512_Last(context);
|
||||
|
||||
/* Save the hash data for output: */
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host byte order */
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
REVERSE64(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Zero out state data */
|
||||
MEMSET_BZERO(context, sizeof(SHA512_CTX));
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
SHA512(void *data, unsigned int data_len, unsigned char *digest)
|
||||
{
|
||||
SHA512_CTX ctx;
|
||||
SHA512_Init(&ctx);
|
||||
SHA512_Update(&ctx, data, data_len);
|
||||
SHA512_Final(digest, &ctx);
|
||||
return digest;
|
||||
}
|
||||
+13
-17
@@ -20,16 +20,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -42,7 +42,6 @@
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#include <limits.h>
|
||||
|
||||
/* for test */
|
||||
/* #define SNPRINTF_TEST 1 */
|
||||
@@ -429,7 +428,7 @@ print_num_llp(char** at, size_t* left, int* ret, void* value,
|
||||
char buf[PRINT_DEC_BUFSZ];
|
||||
int negative = 0;
|
||||
int zero = (value == 0);
|
||||
#if defined(SIZE_MAX) && defined(UINT32_MAX) && (UINT32_MAX == SIZE_MAX || INT32_MAX == SIZE_MAX)
|
||||
#if defined(UINTPTR_MAX) && defined(UINT32_MAX) && (UINTPTR_MAX == UINT32_MAX)
|
||||
/* avoid warning about upcast on 32bit systems */
|
||||
unsigned long long llvalue = (unsigned long)value;
|
||||
#else
|
||||
@@ -658,7 +657,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 +797,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),
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
/* compat/strlcat.c */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. 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.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
|
||||
*/
|
||||
|
||||
/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */
|
||||
|
||||
#include "config.h"
|
||||
#ifndef HAVE_STRLCAT
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
}
|
||||
|
||||
#endif /* !HAVE_STRLCAT */
|
||||
+4
-4
@@ -89,7 +89,7 @@ str2int(const char **buf, int max)
|
||||
{
|
||||
int ret=0, count=0;
|
||||
|
||||
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
|
||||
while (*buf[0] != '\0' && isdigit(*buf[0]) && count<max) {
|
||||
ret = ret*10 + (*buf[0] - '0');
|
||||
(*buf)++;
|
||||
count++;
|
||||
@@ -111,11 +111,11 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
/* whitespace, literal or format */
|
||||
if (isspace((unsigned char)c)) { /* whitespace */
|
||||
if (isspace(c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
* input string.
|
||||
**/
|
||||
while (isspace((unsigned char)*s))
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
}
|
||||
else if (c == '%') { /* format */
|
||||
@@ -221,7 +221,7 @@ unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
break;
|
||||
case 'n': /* arbitrary whitespace */
|
||||
case 't':
|
||||
while (isspace((unsigned char)*s))
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
break;
|
||||
case 'p': /* am pm */
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/**
|
||||
* strsep implementation for compatibility.
|
||||
*
|
||||
* LICENSE
|
||||
* Copyright (c) 2016, NLnet Labs
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 NLnetLabs 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 OWNER 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.
|
||||
**/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
/** see if character is in the delimiter array */
|
||||
static int
|
||||
in_delim(char c, const char* delim)
|
||||
{
|
||||
const char* p;
|
||||
if(!delim)
|
||||
return 0;
|
||||
for(p=delim; *p; p++) {
|
||||
if(*p == c)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *strsep(char **stringp, const char *delim)
|
||||
{
|
||||
char* s;
|
||||
char* orig;
|
||||
if(stringp == NULL || *stringp == NULL)
|
||||
return NULL;
|
||||
orig = *stringp;
|
||||
s = *stringp;
|
||||
while(*s && !in_delim(*s, delim))
|
||||
s++;
|
||||
if(*s) {
|
||||
*s = 0;
|
||||
*stringp = s+1;
|
||||
} else {
|
||||
*stringp = NULL;
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
Vendored
+749
-1031
File diff suppressed because it is too large
Load Diff
+59
-669
File diff suppressed because it is too large
Load Diff
Vendored
+1393
-1582
File diff suppressed because it is too large
Load Diff
+245
-1314
File diff suppressed because it is too large
Load Diff
@@ -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"]
|
||||
+2
-41
@@ -15,46 +15,7 @@ distribution but may be helpful.
|
||||
a local-zone and local-data include file for unbound.conf.
|
||||
* unbound-host.nagios.patch: makes unbound-host return status that fits right
|
||||
in with the nagios monitoring framework. Contributed by Migiel de Vos.
|
||||
* unbound_unixsock.diff: Add Unix socket support for unbound-control.
|
||||
Contributed by Ilya Bakulin, 2012-08-28.
|
||||
* patch_rsamd5_enable.diff: this patch enables RSAMD5 validation (otherwise
|
||||
it is treated as insecure). The RSAMD5 algorithm is deprecated (RFC6725).
|
||||
* create_unbound_ad_servers.sh: shell script to enter anti-ad server lists.
|
||||
* create_unbound_ad_servers.cmd: windows script to enter anti-ad server lists.
|
||||
* unbound_cache.sh: shell script to save and load the cache.
|
||||
* unbound_cache.cmd: windows script to save and load the cache.
|
||||
* warmup.sh: shell script to warm up DNS cache by your own MRU domains.
|
||||
* warmup.cmd: windows script to warm up DNS cache by your own MRU domains.
|
||||
* aaaa-filter-iterator.patch: adds config option aaaa-filter: yes that
|
||||
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.
|
||||
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.
|
||||
* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
|
||||
* unbound-querycachedb.py: utility to show data stored in cachedb backend
|
||||
for a particular query name and type. It requires dnspython and (for
|
||||
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.
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
|
||||
index 5a75e319..c6c6dbe2 100644
|
||||
--- a/doc/unbound.conf.5.in
|
||||
+++ b/doc/unbound.conf.5.in
|
||||
@@ -970,6 +970,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
|
||||
this option in enabled. Only use if you know what you are doing.
|
||||
This option only has effect when qname-minimisation is enabled. Default is no.
|
||||
.TP
|
||||
+.B aaaa\-filter: \fI<yes or no>
|
||||
+Activate behavior similar to BIND's AAAA-filter.
|
||||
+This forces the dropping of all AAAA records, unless in the case of
|
||||
+explicit AAAA queries, when no A records have been confirmed.
|
||||
+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>
|
||||
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 f093c1bf..e55a2246 100644
|
||||
--- a/iterator/iter_scrub.c
|
||||
+++ b/iterator/iter_scrub.c
|
||||
@@ -679,6 +679,32 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ASN: Lookup A records from rrset cache.
|
||||
+ * @param qinfo: the question originally asked.
|
||||
+ * @param env: module environment with config and cache.
|
||||
+ * @param ie: iterator environment with private address data.
|
||||
+ * @return 0 if no A record found, 1 if A record found.
|
||||
+ */
|
||||
+static int
|
||||
+asn_lookup_a_record_from_cache(struct query_info* qinfo,
|
||||
+ struct module_env* env, struct iter_env* ATTR_UNUSED(ie))
|
||||
+{
|
||||
+ struct ub_packed_rrset_key* akey;
|
||||
+
|
||||
+ /* get cached A records for queried name */
|
||||
+ akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname,
|
||||
+ qinfo->qname_len, LDNS_RR_TYPE_A, qinfo->qclass,
|
||||
+ 0, *env->now, 0);
|
||||
+ if(akey) { /* we had some. */
|
||||
+ log_rrset_key(VERB_ALGO, "ASN-AAAA-filter: found A record",
|
||||
+ akey);
|
||||
+ lock_rw_unlock(&akey->entry.lock);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Given a response event, remove suspect RRsets from the response.
|
||||
* "Suspect" rrsets are potentially poison. Note that this routine expects
|
||||
@@ -698,6 +724,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
|
||||
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 */
|
||||
struct rrset_parse* rrset, *prev;
|
||||
@@ -733,6 +760,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
|
||||
+ /* ASN: Locate any A record we can find */
|
||||
+ if((ie->aaaa_filter) && (qinfo->qtype == LDNS_RR_TYPE_AAAA)) {
|
||||
+ found_a_record = asn_lookup_a_record_from_cache(qinfo,
|
||||
+ env, ie);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
+
|
||||
/* 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
|
||||
@@ -744,6 +778,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
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
|
||||
+ * records, no questions asked. If this IS a AAAA query
|
||||
+ * then remove AAAA records if we have an A record.
|
||||
+ * Otherwise, leave things be. */
|
||||
+ if((qinfo->qtype != LDNS_RR_TYPE_AAAA) ||
|
||||
+ (found_a_record)) {
|
||||
+ remove_rrset("ASN-AAAA-filter: removing AAAA "
|
||||
+ "for record", pkt, msg, prev, &rrset);
|
||||
+ continue;
|
||||
+ }
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
|
||||
+ "keep AAAA for", zonename,
|
||||
+ 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 2482a1f4..bd5ba243 100644
|
||||
--- a/iterator/iter_utils.c
|
||||
+++ b/iterator/iter_utils.c
|
||||
@@ -177,6 +177,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;
|
||||
+ iter_env->aaaa_filter = cfg->aaaa_filter;
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/iterator/iterator.c b/iterator/iterator.c
|
||||
index 54006940..768fe202 100644
|
||||
--- a/iterator/iterator.c
|
||||
+++ b/iterator/iterator.c
|
||||
@@ -2155,6 +2155,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
|
||||
|
||||
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.
|
||||
+ * @param id: module id.
|
||||
+ * @return true if the event requires more request processing immediately,
|
||||
+ * false if not. This state only returns true when it is generating
|
||||
+ * a SERVFAIL response because the query has hit a dead end.
|
||||
+ */
|
||||
+static int
|
||||
+asn_processQueryAAAA(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
+ struct iter_env* ATTR_UNUSED(ie), int id)
|
||||
+{
|
||||
+ struct module_qstate* subq = NULL;
|
||||
+
|
||||
+ log_assert(iq->fetch_a_for_aaaa == 0);
|
||||
+
|
||||
+ /* flag the query properly in order to not loop */
|
||||
+ iq->fetch_a_for_aaaa = 1;
|
||||
+
|
||||
+ /* 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.qclass, qstate, id, iq,
|
||||
+ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1, 0)) {
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed "
|
||||
+ "preloading of A record for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass);
|
||||
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
+ }
|
||||
+ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: "
|
||||
+ "preloading records in cache for",
|
||||
+ iq->qchase.qname, LDNS_RR_TYPE_A,
|
||||
+ iq->qchase.qclass);
|
||||
+
|
||||
+ /* set this query as waiting */
|
||||
+ qstate->ext_state[id] = module_wait_subquery;
|
||||
+ /* at this point break loop */
|
||||
+ return 0;
|
||||
+}
|
||||
+/* ASN: End of added code */
|
||||
|
||||
/**
|
||||
* This is the request event state where the request will be sent to one of
|
||||
@@ -2216,6 +2263,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
+ /* ASN: If we have a AAAA query, then also query for A records */
|
||||
+ if((ie->aaaa_filter) && (iq->qchase.qtype == LDNS_RR_TYPE_AAAA) &&
|
||||
+ (iq->fetch_a_for_aaaa == 0)) {
|
||||
+ return next_state(iq, ASN_FETCH_A_FOR_AAAA_STATE);
|
||||
+ }
|
||||
+ /* ASN: End of added code */
|
||||
+
|
||||
/* Make sure we have a delegation point, otherwise priming failed
|
||||
* or another failure occurred */
|
||||
if(!iq->dp) {
|
||||
@@ -3648,6 +3702,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
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.
|
||||
+ * This is required down the road to decide whether to scrub AAAA records
|
||||
+ * from the results or not.
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param id: module id.
|
||||
+ * @param forq: super query state.
|
||||
+ */
|
||||
+static void
|
||||
+asn_processAAAAResponse(struct module_qstate* qstate, int id,
|
||||
+ struct module_qstate* super)
|
||||
+{
|
||||
+ /*struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id];*/
|
||||
+ struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id];
|
||||
+ struct delegpt_ns* dpns = NULL;
|
||||
+ int error = (qstate->return_rcode != LDNS_RCODE_NOERROR);
|
||||
+
|
||||
+ log_assert(super_iq->fetch_a_for_aaaa > 0);
|
||||
+
|
||||
+ /* let super go to evaluation of targets after this */
|
||||
+ super_iq->state = QUERYTARGETS_STATE;
|
||||
+
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse",
|
||||
+ &qstate->qinfo);
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse super",
|
||||
+ &super->qinfo);
|
||||
+
|
||||
+ if(super_iq->dp)
|
||||
+ dpns = delegpt_find_ns(super_iq->dp,
|
||||
+ qstate->qinfo.qname, qstate->qinfo.qname_len);
|
||||
+ if (!dpns) {
|
||||
+ /* not interested */
|
||||
+ verbose(VERB_ALGO, "ASN-AAAA-filter: subq: %s, but parent not "
|
||||
+ "interested%s", (error ? "error, but" : "success"),
|
||||
+ (super_iq->dp ? "anymore" : " (was reset)"));
|
||||
+ log_query_info(VERB_ALGO, "ASN-AAAA-filter: superq", &super->qinfo);
|
||||
+ if(super_iq->dp && error)
|
||||
+ delegpt_log(VERB_ALGO, super_iq->dp);
|
||||
+ return;
|
||||
+ } else if (error) {
|
||||
+ verbose(VERB_ALGO, "ASN-AAAA-filter: mark as failed, "
|
||||
+ "and go to target query.");
|
||||
+ /* see if the failure did get (parent-lame) info */
|
||||
+ if(!cache_fill_missing(super->env,
|
||||
+ super_iq->qchase.qclass, super->region,
|
||||
+ super_iq->dp))
|
||||
+ log_err("ASN-AAAA-filter: out of memory adding missing");
|
||||
+ dpns->resolved = 1; /* mark as failed */
|
||||
+ }
|
||||
+}
|
||||
+/* ASN: End of added code */
|
||||
+
|
||||
/*
|
||||
* Return priming query results to interested super querystates.
|
||||
*
|
||||
@@ -3667,6 +3776,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
|
||||
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
|
||||
super->minfo[id])->state == DSNS_FIND_STATE)
|
||||
processDSNSResponse(qstate, id, super);
|
||||
+ else if (super->qinfo.qtype == LDNS_RR_TYPE_AAAA && ((struct iter_qstate*)
|
||||
+ super->minfo[id])->state == ASN_FETCH_A_FOR_AAAA_STATE)
|
||||
+ asn_processAAAAResponse(qstate, id, super);
|
||||
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
|
||||
error_supers(qstate, id, super);
|
||||
else if(qstate->is_priming)
|
||||
@@ -3704,6 +3816,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
case INIT_REQUEST_3_STATE:
|
||||
cont = processInitRequest3(qstate, iq, id);
|
||||
break;
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE:
|
||||
+ cont = asn_processQueryAAAA(qstate, iq, ie, id);
|
||||
+ break;
|
||||
case QUERYTARGETS_STATE:
|
||||
cont = processQueryTargets(qstate, iq, ie, id);
|
||||
break;
|
||||
@@ -4040,6 +4155,8 @@ iter_state_to_string(enum iter_state state)
|
||||
return "INIT REQUEST STATE (stage 2)";
|
||||
case INIT_REQUEST_3_STATE:
|
||||
return "INIT REQUEST STATE (stage 3)";
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE:
|
||||
+ return "ASN_FETCH_A_FOR_AAAA_STATE";
|
||||
case QUERYTARGETS_STATE :
|
||||
return "QUERY TARGETS STATE";
|
||||
case PRIME_RESP_STATE :
|
||||
@@ -4064,6 +4181,7 @@ iter_state_is_responsestate(enum iter_state s)
|
||||
case INIT_REQUEST_STATE :
|
||||
case INIT_REQUEST_2_STATE :
|
||||
case INIT_REQUEST_3_STATE :
|
||||
+ case ASN_FETCH_A_FOR_AAAA_STATE :
|
||||
case QUERYTARGETS_STATE :
|
||||
case COLLECT_CLASS_STATE :
|
||||
return 0;
|
||||
diff --git a/iterator/iterator.h b/iterator/iterator.h
|
||||
index 8b840528..a61c4195 100644
|
||||
--- a/iterator/iterator.h
|
||||
+++ b/iterator/iterator.h
|
||||
@@ -133,6 +133,9 @@ struct iter_env {
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
|
||||
+ /** ASN: AAAA-filter flag */
|
||||
+ int aaaa_filter;
|
||||
+
|
||||
/** lock on ratelimit counter */
|
||||
lock_basic_type queries_ratelimit_lock;
|
||||
/** number of queries that have been ratelimited */
|
||||
@@ -187,6 +190,14 @@ enum iter_state {
|
||||
*/
|
||||
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
|
||||
+ * work.
|
||||
+ */
|
||||
+ 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.
|
||||
@@ -376,6 +387,13 @@ struct iter_qstate {
|
||||
*/
|
||||
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 1ca8686a..d91b19ec 100644
|
||||
--- a/pythonmod/interface.i
|
||||
+++ b/pythonmod/interface.i
|
||||
@@ -995,6 +995,7 @@ struct config_file {
|
||||
int harden_dnssec_stripped;
|
||||
int harden_referral_path;
|
||||
int use_caps_bits_for_id;
|
||||
+ int aaaa_filter; /* ASN */
|
||||
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 969d664b..8d94b008 100644
|
||||
--- a/util/config_file.c
|
||||
+++ b/util/config_file.c
|
||||
@@ -231,6 +231,7 @@ config_create(void)
|
||||
cfg->harden_referral_path = 0;
|
||||
cfg->harden_algo_downgrade = 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 c7c9a0a4..e3aa15b0 100644
|
||||
--- a/util/config_file.h
|
||||
+++ b/util/config_file.h
|
||||
@@ -285,6 +285,8 @@ struct config_file {
|
||||
int harden_algo_downgrade;
|
||||
/** use 0x20 bits in query as random ID bits */
|
||||
int use_caps_bits_for_id;
|
||||
+ /** ASN: enable AAAA filter? */
|
||||
+ int aaaa_filter;
|
||||
/** 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 34a0e5dd..c890be2a 100644
|
||||
--- a/util/configlexer.lex
|
||||
+++ b/util/configlexer.lex
|
||||
@@ -317,6 +317,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 d4f965f9..8cc237c6 100644
|
||||
--- a/util/configparser.y
|
||||
+++ b/util/configparser.y
|
||||
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%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
|
||||
@@ -247,6 +248,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
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_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 |
|
||||
@@ -1754,6 +1756,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
|
||||
+ {
|
||||
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
|
||||
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
+ 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));
|
||||
@@ -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",
|
||||
},
|
||||
);
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading Expat"
|
||||
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to download Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking Expat"
|
||||
rm -rf ./expat-2.2.9
|
||||
if ! tar -xf expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd expat-2.2.9 || exit 1
|
||||
|
||||
echo "Configuring Expat"
|
||||
if ! ./configure --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" --prefix="$ANDROID_PREFIX"; then
|
||||
echo "Error: Failed to configure Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
|
||||
echo "Fixing Makefiles"
|
||||
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
|
||||
do
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
done)
|
||||
|
||||
echo "Building Expat"
|
||||
if ! make; then
|
||||
echo "Failed to build Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Expat"
|
||||
if ! make install; then
|
||||
echo "Failed to install Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,33 +0,0 @@
|
||||
@Echo off
|
||||
rem Convert the Yoyo.org anti-ad server listing
|
||||
rem into an unbound dns spoof redirection list.
|
||||
rem Written by Y.Voinov (c) 2014
|
||||
|
||||
rem Note: Wget required!
|
||||
|
||||
rem Variables
|
||||
set prefix="C:\Program Files (x86)"
|
||||
set dst_dir=%prefix%\Unbound
|
||||
set work_dir=%TEMP%
|
||||
set list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
|
||||
|
||||
rem Check Wget installed
|
||||
for /f "delims=" %%a in ('where wget') do @set wget=%%a
|
||||
if /I "%wget%"=="" echo Wget not found. If installed, add path to PATH environment variable. & exit 1
|
||||
echo Wget found: %wget%
|
||||
|
||||
"%wget%" -O %work_dir%\yoyo_ad_servers %list_addr%
|
||||
|
||||
del /Q /F /S %dst_dir%\unbound_ad_servers
|
||||
|
||||
for /F "eol=; tokens=*" %%a in (%work_dir%\yoyo_ad_servers) do (
|
||||
echo local-zone: %%a redirect>>%dst_dir%\unbound_ad_servers
|
||||
echo local-data: "%%a A 127.0.0.1">>%dst_dir%\unbound_ad_servers
|
||||
)
|
||||
|
||||
echo Done.
|
||||
rem then add an include line to your unbound.conf pointing to the full path of
|
||||
rem the unbound_ad_servers file:
|
||||
rem
|
||||
rem include: $dst_dir/unbound_ad_servers
|
||||
rem
|
||||
@@ -1,42 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Convert the Yoyo.org anti-ad server listing
|
||||
# into an unbound dns spoof redirection list.
|
||||
# Modified by Y.Voinov (c) 2014
|
||||
|
||||
# Note: Wget required!
|
||||
|
||||
# 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="
|
||||
|
||||
# OS commands
|
||||
CAT=`which cat`
|
||||
ECHO=`which echo`
|
||||
WGET=`which wget`
|
||||
TR=`which tr`
|
||||
|
||||
# Check Wget installed
|
||||
if [ ! -f $WGET ]; then
|
||||
echo "Wget not found. Exiting..."
|
||||
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" ;\
|
||||
$ECHO "local-data: \"$line A 127.0.0.1\"" ;\
|
||||
done > \
|
||||
$dst_dir/unbound_ad_servers
|
||||
|
||||
echo "Done."
|
||||
# then add an include line to your unbound.conf pointing to the full path of
|
||||
# the unbound_ad_servers file:
|
||||
#
|
||||
# include: $dst_dir/unbound_ad_servers
|
||||
#
|
||||
@@ -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));
|
||||
@@ -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;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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"),
|
||||
},
|
||||
);
|
||||
@@ -1,56 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
echo "Downloading Expat"
|
||||
if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to download Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Unpacking Expat"
|
||||
rm -rf ./expat-2.2.9
|
||||
if ! tar -xf expat-2.2.9.tar.gz;
|
||||
then
|
||||
echo "Failed to unpack Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd expat-2.2.9 || exit 1
|
||||
|
||||
export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
|
||||
|
||||
echo "Configuring Expat"
|
||||
if ! ./configure \
|
||||
--build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
|
||||
--prefix="$IOS_PREFIX" ; then
|
||||
echo "Error: Failed to configure Expat"
|
||||
cat config.log
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Cleanup warnings, https://github.com/libexpat/libexpat/issues/383
|
||||
echo "Fixing Makefiles"
|
||||
(IFS="" find "$PWD" -name 'Makefile' -print | while read -r file
|
||||
do
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wduplicated-cond ||g; s|-Wduplicated-branches ||g; s|-Wlogical-op ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
|
||||
cp -p "$file" "$file.fixed"
|
||||
sed 's|-Wrestrict ||g; s|-Wjump-misses-init ||g; s|-Wmisleading-indentation ||g' "$file" > "$file.fixed"
|
||||
mv "$file.fixed" "$file"
|
||||
done)
|
||||
|
||||
echo "Building Expat"
|
||||
if ! make; then
|
||||
echo "Failed to build Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing Expat"
|
||||
if ! make install; then
|
||||
echo "Failed to install Expat"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -1,52 +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/ios/15-ios.conf Configurations/; then
|
||||
echo "Failed to copy OpenSSL ios config"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# OpenSSL 1.1.1d patch. OK to remove once OpenSSL version is bumped.
|
||||
# ocsp.c:947:23: error: 'fork' is unavailable: not available on tvOS and watchOS.
|
||||
# Also see https://github.com/openssl/openssl/issues/7607.
|
||||
if ! patch -u -p0 < ../contrib/ios/openssl.patch; then
|
||||
echo "Failed to patch OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Configuring OpenSSL"
|
||||
if ! ./Configure "$OPENSSL_HOST" -DNO_FORK no-comp no-asm no-hw no-engine no-tests no-unit-test \
|
||||
--prefix="$IOS_PREFIX" --openssldir="$IOS_PREFIX"; then
|
||||
echo "Failed to configure OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building OpenSSL"
|
||||
if ! make; then
|
||||
echo "Failed to build OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Installing OpenSSL"
|
||||
if ! make install_sw; then
|
||||
echo "Failed to install OpenSSL"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,274 +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=
|
||||
for i in $(seq -f "%.1f" 30.0 -0.1 1.0)
|
||||
do
|
||||
if [ -d "$XCODE_DEVELOPER_SDK/Developer/SDKs/$IOS_SDK$i.sdk" ]; then
|
||||
XCODE_SDK="$IOS_SDK$i.sdk"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# Error checking
|
||||
if [ -z "$XCODE_SDK" ]; then
|
||||
echo "ERROR: unable to find a SDK."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
IOS_SYSROOT="$XCODE_DEVELOPER_SDK/Developer/SDKs/$XCODE_SDK"
|
||||
|
||||
if [ -z "$IOS_SYSROOT" ] || [ ! -d "$IOS_SYSROOT" ]; then
|
||||
echo "ERROR: unable to find IOS_SYSROOT directory."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
# We want to set AR=libtool and ARFLAGS="-static -o",
|
||||
# but I am not sure Autotools can handle it.
|
||||
CPP=cpp; CC=clang; CXX=clang++; LD=ld
|
||||
AS=as; AR=ar; RANLIB=ranlib; STRIP=strip
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$CC" ]; then
|
||||
echo "ERROR: Failed to find iOS clang. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$CXX" ]; then
|
||||
echo "ERROR: Failed to find iOS clang++. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$RANLIB" ]; then
|
||||
echo "ERROR: Failed to find iOS ranlib. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$AR" ]; then
|
||||
echo "ERROR: Failed to find iOS ar. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$AS" ]; then
|
||||
echo "ERROR: Failed to find iOS as. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
# Error checking
|
||||
if [ ! -e "$XCODE_TOOLCHAIN/$LD" ]; then
|
||||
echo "ERROR: Failed to find iOS ld. Please edit this script."
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 1 || return 1
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
LENGTH=${#XCODE_TOOLCHAIN}
|
||||
SUBSTR=${PATH:0:$LENGTH}
|
||||
if [ "$SUBSTR" != "$XCODE_TOOLCHAIN" ]; then
|
||||
export PATH="$XCODE_TOOLCHAIN":"$PATH"
|
||||
fi
|
||||
|
||||
#####################################################################
|
||||
|
||||
export CPP CC CXX LD AS AR RANLIB STRIP
|
||||
export IOS_SYSROOT
|
||||
export CFLAGS="-arch $IOS_CPU $MIN_VER --sysroot=$IOS_SYSROOT"
|
||||
export CXXFLAGS="-arch $IOS_CPU $MIN_VER -stdlib-libc++ --sysroot=$IOS_SYSROOT"
|
||||
|
||||
#####################################################################
|
||||
|
||||
echo "XCODE_TOOLCHAIN: $XCODE_TOOLCHAIN"
|
||||
|
||||
echo "CPP: $(command -v "$CPP")"
|
||||
echo "CC: $(command -v "$CC")"
|
||||
echo "CXX: $(command -v "$CXX")"
|
||||
echo "LD: $(command -v "$LD")"
|
||||
echo "AS: $(command -v "$AS")"
|
||||
echo "AR: $(command -v "$AR")"
|
||||
|
||||
echo "IOS_SYSROOT: $IOS_SYSROOT"
|
||||
|
||||
echo "CPPFLAGS: $CPPFLAGS"
|
||||
echo "CFLAGS: $CFLAGS"
|
||||
echo "CXXFLAGS: $CXXFLAGS"
|
||||
|
||||
[ "$0" = "${BASH_SOURCE[0]}" ] && exit 0 || return 0
|
||||
@@ -1,13 +0,0 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
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
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
@@ -1,42 +0,0 @@
|
||||
# See ltrace.conf(5) for description of syntax of this file.
|
||||
typedef ub_type = enum(TYPE_A=1,TYPE_NS=2,TYPE_SOA=6,TYPE_MX=15,TYPE_TXT=16,TYPE_AAAA=28,TYPE_DS=43,TYPE_DNSKEY=48,TYPE_TLSA=52,TYPE_ANY=255);
|
||||
typedef ub_class = enum(CLASS_IN=1,CLASS_CH=3,CLASS_NONE=254,CLASS_ANY=255);
|
||||
typedef ub_rcode = enum(RCODE_NOERROR,RCODE_FORMERR,RCODE_SERVFAIL,RCODE_NXDOMAIN,RCODE_NOTIMPL,RCODE_REFUSED,RCODE_YXDOMAIN,RCODE_YXRRSET,RCODE_NXRRSET,RCODE_NOTAUTH,RCODE_NOTZONE);
|
||||
typedef ub_havedata = enum(no_data, have_data);
|
||||
typedef ub_nxdomain = enum(name_exists, nxdomain);
|
||||
typedef ub_secure = enum(not_secure, secure);
|
||||
typedef ub_bogus = enum(not_bogus, bogus);
|
||||
typedef ub_result = struct(string, ub_type, ub_class, array(void*,zero)*, array(int,zero)*, string, ub_rcode, void*, int, ub_havedata, ub_nxdomain, ub_secure, ub_bogus, string, int);
|
||||
typedef ub_ctx = void;
|
||||
ub_ctx* ub_ctx_create(void);
|
||||
void ub_ctx_delete(ub_ctx*);
|
||||
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);
|
||||
int ub_ctx_add_ta(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_file(ub_ctx*, string);
|
||||
int ub_ctx_add_ta_autr(ub_ctx*, string);
|
||||
int ub_ctx_trustedkeys(ub_ctx*, string);
|
||||
int ub_ctx_debugout(ub_ctx*, void*);
|
||||
int ub_ctx_debuglevel(ub_ctx*, int);
|
||||
int ub_ctx_async(ub_ctx*, bool(int));
|
||||
int ub_poll(ub_ctx*);
|
||||
int ub_wait(ub_ctx*);
|
||||
int ub_fd(ub_ctx*);
|
||||
int ub_process(ub_ctx*);
|
||||
int ub_resolve(ub_ctx*, string, ub_type, ub_class, +ub_result**);
|
||||
int ub_resolve_async(ub_ctx*, string, ub_type, ub_class, void*, void*, +int*);
|
||||
int ub_cancel(ub_ctx*, int);
|
||||
void ub_resolve_free(ub_result*);
|
||||
string ub_strerror(int);
|
||||
int ub_ctx_print_local_zones(ub_ctx*);
|
||||
int ub_ctx_zone_add(ub_ctx*, string, string);
|
||||
int ub_ctx_zone_remove(ub_ctx*, string);
|
||||
int ub_ctx_data_add(ub_ctx*, string);
|
||||
int ub_ctx_data_remove(ub_ctx*, string);
|
||||
string ub_version(void);
|
||||
@@ -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 ""
|
||||
}
|
||||
@@ -91,7 +91,7 @@ while ( scalar keys %startstats < $numthreads || scalar keys %donestats < $numth
|
||||
$allstats{$inthread}->{outstandingexc} = $4;
|
||||
}
|
||||
elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) {
|
||||
$allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to millisec.
|
||||
$allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec.
|
||||
}
|
||||
elsif ( $line =~ m/info: histogram of recursion processing times/ ) {
|
||||
next;
|
||||
@@ -103,7 +103,7 @@ while ( scalar keys %startstats < $numthreads || scalar keys %donestats < $numth
|
||||
}
|
||||
elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) {
|
||||
# since after this line we're unsure if we get these numbers
|
||||
# at all, we should consider this marker as the end of the
|
||||
# at all, we sould consider this marker as the end of the
|
||||
# block. Chances that we're parsing a file halfway written
|
||||
# at this stage are small. Bold statement.
|
||||
$donestats{$inthread} = 1;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,344 +0,0 @@
|
||||
Index: daemon/worker.c
|
||||
===================================================================
|
||||
--- daemon/worker.c (revision 4191)
|
||||
+++ daemon/worker.c (working copy)
|
||||
@@ -663,8 +663,21 @@
|
||||
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
|
||||
LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
|
||||
goto bail_out;
|
||||
- error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
- qinfo, id, flags, edns);
|
||||
+ if (qinfo->qtype == LDNS_RR_TYPE_A &&
|
||||
+ worker->env.cfg->redirect_bogus_ipv4) {
|
||||
+ /* BAD cached */
|
||||
+ fixed_address_encode(repinfo->c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
|
||||
+ worker->env.cfg->redirect_bogus_ipv4);
|
||||
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA &&
|
||||
+ worker->env.cfg->redirect_bogus_ipv6) {
|
||||
+ fixed_address_encode(repinfo->c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
|
||||
+ worker->env.cfg->redirect_bogus_ipv6);
|
||||
+ } else {
|
||||
+ error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
+ qinfo, id, flags, edns);
|
||||
+ }
|
||||
rrset_array_unlock_touch(worker->env.rrset_cache,
|
||||
worker->scratchpad, rep->ref, rep->rrset_count);
|
||||
if(worker->stats.extended) {
|
||||
Index: doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- doc/unbound.conf.5.in (revision 4191)
|
||||
+++ doc/unbound.conf.5.in (working copy)
|
||||
@@ -1244,6 +1244,18 @@
|
||||
This can make ordinary queries complete (if repeatedly queried for),
|
||||
and enter the cache, whilst also mitigating the traffic flow by the
|
||||
factor given.
|
||||
+.TP 5
|
||||
+.B redirect-bogus-ipv4: \fI<IPv4 address>
|
||||
+Set a fixed address for DNSSEC failures that are cached
|
||||
+Instead of responding to A queries with SERVFAIL, respond
|
||||
+with NOERROR and the address specified here
|
||||
+The TTL of the response will be 5 seconds
|
||||
+.TP 5
|
||||
+.B redirect-bogus-ipv6: \fI<IPv4 address>
|
||||
+Set a fixed address for DNSSEC failures that are cached
|
||||
+Instead of responding to AAAA queries with SERVFAIL, respond
|
||||
+with NOERROR and the address specified here
|
||||
+The TTL of the response will be 5 seconds
|
||||
.SS "Remote Control Options"
|
||||
In the
|
||||
.B remote\-control:
|
||||
Index: services/mesh.c
|
||||
===================================================================
|
||||
--- services/mesh.c (revision 4191)
|
||||
+++ services/mesh.c (working copy)
|
||||
@@ -1006,6 +1006,7 @@
|
||||
struct timeval end_time;
|
||||
struct timeval duration;
|
||||
int secure;
|
||||
+ int bogus_override = 0;
|
||||
/* Copy the client's EDNS for later restore, to make sure the edns
|
||||
* compare is with the correct edns options. */
|
||||
struct edns_data edns_bak = r->edns;
|
||||
@@ -1016,6 +1017,7 @@
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
if(m->s.env->cfg->stat_extended)
|
||||
m->s.env->mesh->ans_bogus++;
|
||||
+ bogus_override = 1;
|
||||
}
|
||||
if(rep && rep->security == sec_status_secure)
|
||||
secure = 1;
|
||||
@@ -1047,17 +1049,34 @@
|
||||
} else if(rcode) {
|
||||
m->s.qinfo.qname = r->qname;
|
||||
m->s.qinfo.local_alias = r->local_alias;
|
||||
- if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
- if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
|
||||
- rep, rcode, &r->edns, m->s.region))
|
||||
- r->edns.opt_list = NULL;
|
||||
- } else {
|
||||
- if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
|
||||
- &r->edns, m->s.region))
|
||||
- r->edns.opt_list = NULL;
|
||||
+ if(bogus_override && m->s.qinfo.qtype == LDNS_RR_TYPE_A &&
|
||||
+ m->s.env->cfg->redirect_bogus_ipv4) {
|
||||
+ fixed_address_encode(r->query_reply.c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
|
||||
+ r->qflags, &r->edns,
|
||||
+ m->s.env->cfg->redirect_bogus_ipv4);
|
||||
+ } else if(bogus_override &&
|
||||
+ m->s.qinfo.qtype == LDNS_RR_TYPE_AAAA &&
|
||||
+ m->s.env->cfg->redirect_bogus_ipv6) {
|
||||
+ fixed_address_encode(r->query_reply.c->buffer,
|
||||
+ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
|
||||
+ r->qflags, &r->edns,
|
||||
+ m->s.env->cfg->redirect_bogus_ipv6);
|
||||
+ } else {
|
||||
+ if(rcode == LDNS_RCODE_SERVFAIL) {
|
||||
+ if(!inplace_cb_reply_servfail_call(m->s.env,
|
||||
+ &m->s.qinfo, &m->s,
|
||||
+ rep, rcode, &r->edns, m->s.region))
|
||||
+ r->edns.opt_list = NULL;
|
||||
+ } else {
|
||||
+ if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo,
|
||||
+ &m->s, rep, rcode, &r->edns,
|
||||
+ m->s.region))
|
||||
+ r->edns.opt_list = NULL;
|
||||
+ }
|
||||
+ error_encode(r->query_reply.c->buffer, rcode,
|
||||
+ &m->s.qinfo, r->qid, r->qflags, &r->edns);
|
||||
}
|
||||
- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
|
||||
- r->qid, r->qflags, &r->edns);
|
||||
comm_point_send_reply(&r->query_reply);
|
||||
} else {
|
||||
size_t udp_size = r->edns.udp_size;
|
||||
Index: util/config_file.c
|
||||
===================================================================
|
||||
--- util/config_file.c (revision 4191)
|
||||
+++ util/config_file.c (working copy)
|
||||
@@ -273,6 +273,8 @@
|
||||
cfg->ratelimit_factor = 10;
|
||||
cfg->qname_minimisation = 0;
|
||||
cfg->qname_minimisation_strict = 0;
|
||||
+ cfg->redirect_bogus_ipv4 = NULL;
|
||||
+ cfg->redirect_bogus_ipv6 = NULL;
|
||||
cfg->shm_enable = 0;
|
||||
cfg->shm_key = 11777;
|
||||
cfg->dnscrypt = 0;
|
||||
@@ -602,6 +604,10 @@
|
||||
}
|
||||
oi[cfg->num_out_ifs++] = d;
|
||||
cfg->out_ifs = oi;
|
||||
+ } else if (strcmp(opt, "redirect-bogus-ipv4:") == 0) {
|
||||
+ cfg->redirect_bogus_ipv4 = strdup(val);
|
||||
+ } else if (strcmp(opt, "redirect-bogus-ipv6:") == 0) {
|
||||
+ cfg->redirect_bogus_ipv6 = strdup(val);
|
||||
} else {
|
||||
/* unknown or unsupported (from the set_option interface):
|
||||
* interface, outgoing-interface, access-control,
|
||||
@@ -1250,6 +1256,12 @@
|
||||
free(cfg->dnstap_version);
|
||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
+ if (cfg->redirect_bogus_ipv4) {
|
||||
+ free(cfg->redirect_bogus_ipv4);
|
||||
+ }
|
||||
+ if (cfg->redirect_bogus_ipv6) {
|
||||
+ free(cfg->redirect_bogus_ipv6);
|
||||
+ }
|
||||
#ifdef USE_IPSECMOD
|
||||
free(cfg->ipsecmod_hook);
|
||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||
Index: util/config_file.h
|
||||
===================================================================
|
||||
--- util/config_file.h (revision 4191)
|
||||
+++ util/config_file.h (working copy)
|
||||
@@ -444,6 +444,9 @@
|
||||
/** minimise QNAME in strict mode, minimise according to RFC.
|
||||
* Do not apply fallback */
|
||||
int qname_minimisation_strict;
|
||||
+ /** construct fake responses for DNSSEC failures */
|
||||
+ char *redirect_bogus_ipv4;
|
||||
+ char *redirect_bogus_ipv6;
|
||||
/** SHM data - true if shm is enabled */
|
||||
int shm_enable;
|
||||
/** SHM data - key for the shm */
|
||||
Index: util/configlexer.lex
|
||||
===================================================================
|
||||
--- util/configlexer.lex (revision 4191)
|
||||
+++ util/configlexer.lex (working copy)
|
||||
@@ -410,6 +410,8 @@
|
||||
response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
|
||||
response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
|
||||
response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
|
||||
+redirect-bogus-ipv4{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV4) }
|
||||
+redirect-bogus-ipv6{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV6) }
|
||||
dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) }
|
||||
dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) }
|
||||
dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
|
||||
Index: util/configparser.y
|
||||
===================================================================
|
||||
--- util/configparser.y (revision 4191)
|
||||
+++ util/configparser.y (working copy)
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#include "sldns/str2wire.h"
|
||||
#include "util/configyyrename.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
@@ -141,6 +142,7 @@
|
||||
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
|
||||
%token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
|
||||
+%token VAR_REDIRECT_BOGUS_IPV4 VAR_REDIRECT_BOGUS_IPV6
|
||||
%token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
|
||||
%token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
|
||||
%token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
|
||||
@@ -228,6 +230,7 @@
|
||||
server_access_control_tag_data | server_access_control_view |
|
||||
server_qname_minimisation_strict | server_serve_expired |
|
||||
server_fake_dsa | server_log_identity | server_use_systemd |
|
||||
+ server_redirect_bogus_ipv4 | server_redirect_bogus_ipv6 |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
server_hide_trustanchor | server_trust_anchor_signaling |
|
||||
@@ -1873,6 +1876,34 @@
|
||||
#endif
|
||||
}
|
||||
;
|
||||
+server_redirect_bogus_ipv4: VAR_REDIRECT_BOGUS_IPV4 STRING_ARG
|
||||
+ {
|
||||
+ uint8_t data[4];
|
||||
+ size_t data_len = 4;
|
||||
+ OUTYY(("P(name:%s)\n", $2));
|
||||
+ if(cfg_parser->cfg->redirect_bogus_ipv4) {
|
||||
+ yyerror("redirect-bogus-ipv4, can only use one address");
|
||||
+ }
|
||||
+ if(sldns_str2wire_a_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
|
||||
+ yyerror("redirect-bogus-ipv4, not a valid IPv4 address");
|
||||
+ }
|
||||
+ free(cfg_parser->cfg->redirect_bogus_ipv4);
|
||||
+ cfg_parser->cfg->redirect_bogus_ipv4 = $2;
|
||||
+ }
|
||||
+server_redirect_bogus_ipv6: VAR_REDIRECT_BOGUS_IPV6 STRING_ARG
|
||||
+ {
|
||||
+ uint8_t data[16];
|
||||
+ size_t data_len = 16;
|
||||
+ OUTYY(("P(name:%s)\n", $2));
|
||||
+ if(cfg_parser->cfg->redirect_bogus_ipv6) {
|
||||
+ yyerror("redirect-bogus-ipv6, can only use one address");
|
||||
+ }
|
||||
+ if(sldns_str2wire_aaaa_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
|
||||
+ yyerror("redirect-bogus-ipv6, not a valid IPv6 address");
|
||||
+ }
|
||||
+ free(cfg_parser->cfg->redirect_bogus_ipv6);
|
||||
+ cfg_parser->cfg->redirect_bogus_ipv6 = $2;
|
||||
+ }
|
||||
stub_name: VAR_NAME STRING_ARG
|
||||
{
|
||||
OUTYY(("P(name:%s)\n", $2));
|
||||
Index: util/data/msgencode.c
|
||||
===================================================================
|
||||
--- util/data/msgencode.c (revision 4191)
|
||||
+++ util/data/msgencode.c (working copy)
|
||||
@@ -48,6 +48,7 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
+#include "sldns/str2wire.h"
|
||||
#include "services/localzone.h"
|
||||
|
||||
/** return code that means the function ran out of memory. negative so it does
|
||||
@@ -914,3 +915,63 @@
|
||||
attach_edns_record(buf, &es);
|
||||
}
|
||||
}
|
||||
+
|
||||
+void
|
||||
+fixed_address_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
|
||||
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* data)
|
||||
+{
|
||||
+ uint16_t flags;
|
||||
+ uint8_t addr_data[16];
|
||||
+ size_t addr_len = 16;
|
||||
+ if (qinfo->qtype == LDNS_RR_TYPE_A) {
|
||||
+ sldns_str2wire_a_buf(data, addr_data, &addr_len);
|
||||
+ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA) {
|
||||
+ sldns_str2wire_aaaa_buf(data, addr_data, &addr_len);
|
||||
+ } else {
|
||||
+ return error_encode(buf, LDNS_RCODE_NOERROR, qinfo, qid, qflags, edns);
|
||||
+ }
|
||||
+ sldns_buffer_clear(buf);
|
||||
+ sldns_buffer_write(buf, &qid, sizeof(uint16_t));
|
||||
+ flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
|
||||
+ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
|
||||
+ sldns_buffer_write_u16(buf, flags);
|
||||
+ if(qinfo) flags = 1;
|
||||
+ else flags = 0;
|
||||
+ sldns_buffer_write_u16(buf, flags);
|
||||
+ sldns_buffer_write_u16(buf, 1);
|
||||
+ flags = 0;
|
||||
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
|
||||
+ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
|
||||
+ if(qinfo) {
|
||||
+ // query
|
||||
+ if(sldns_buffer_current(buf) == qinfo->qname)
|
||||
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
|
||||
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qtype);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qclass);
|
||||
+ // faked answer
|
||||
+ if(sldns_buffer_current(buf) == qinfo->qname)
|
||||
+ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
|
||||
+ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qtype);
|
||||
+ sldns_buffer_write_u16(buf, qinfo->qclass);
|
||||
+ sldns_buffer_write_u16(buf, 0);
|
||||
+ // TTL. Should we make this configurable too?
|
||||
+ sldns_buffer_write_u16(buf, 5);
|
||||
+ sldns_buffer_write_u16(buf, addr_len);
|
||||
+ sldns_buffer_write(buf, addr_data, addr_len);
|
||||
+ fflush(stderr);
|
||||
+ }
|
||||
+ sldns_buffer_flip(buf);
|
||||
+ if(edns) {
|
||||
+ struct edns_data es = *edns;
|
||||
+ es.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
+ es.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
+ es.ext_rcode = 0;
|
||||
+ es.bits &= EDNS_DO;
|
||||
+ if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
|
||||
+ edns->udp_size)
|
||||
+ return;
|
||||
+ attach_edns_record(buf, &es);
|
||||
+ }
|
||||
+}
|
||||
Index: util/data/msgencode.h
|
||||
===================================================================
|
||||
--- util/data/msgencode.h (revision 4191)
|
||||
+++ util/data/msgencode.h (working copy)
|
||||
@@ -128,4 +128,20 @@
|
||||
void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
|
||||
uint16_t qid, uint16_t qflags, struct edns_data* edns);
|
||||
|
||||
+/**
|
||||
+ * Encode a fixed address response.
|
||||
+ * This is a fake answer to either an A or AAA query
|
||||
+ *
|
||||
+ * It will answer with that address
|
||||
+ *
|
||||
+ * @param pkt: where to store the packet.
|
||||
+ * @param r: RCODE value to encode.
|
||||
+ * @param qinfo: if not NULL, the query is included.
|
||||
+ * @param qid: query ID to set in packet. network order.
|
||||
+ * @param qflags: original query flags (to copy RD and CD bits). host order.
|
||||
+ * @param edns: if not NULL, this is the query edns info,
|
||||
+ * and an edns reply is attached. Only attached if EDNS record fits reply.
|
||||
+ */
|
||||
+void fixed_address_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
|
||||
+ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* address);
|
||||
#endif /* UTIL_DATA_MSGENCODE_H */
|
||||
Binary file not shown.
@@ -1,148 +0,0 @@
|
||||
>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001
|
||||
From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
|
||||
Date: Wed, 2 Jan 2019 22:52:51 -0800
|
||||
Subject: [PATCH] Add unbound-fuzzme.
|
||||
|
||||
This is a small program that simply parses a packet provided on stdout,
|
||||
for the purposes of fuzzing.
|
||||
---
|
||||
.gitignore | 1 +
|
||||
Makefile.in | 22 ++++++++++++++++++++--
|
||||
smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 59 insertions(+), 2 deletions(-)
|
||||
create mode 100644 smallapp/unbound-fuzzme.c
|
||||
|
||||
diff --git a/.gitignore b/.gitignore
|
||||
index f4527fd8..6163f905 100644
|
||||
--- a/.gitignore
|
||||
+++ b/.gitignore
|
||||
@@ -24,6 +24,7 @@
|
||||
/unbound-checkconf
|
||||
/unbound-control
|
||||
/unbound-control-setup
|
||||
+/unbound-fuzzme
|
||||
/unbound-host
|
||||
/unbound.h
|
||||
/asynclook
|
||||
diff --git a/Makefile.in b/Makefile.in
|
||||
index af5b10f6..dacf1ab5 100644
|
||||
--- a/Makefile.in
|
||||
+++ b/Makefile.in
|
||||
@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \
|
||||
worker.lo @WIN_DAEMON_OBJ@
|
||||
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
|
||||
+FUZZME_SRC=smallapp/unbound-fuzzme.c
|
||||
+FUZZME_OBJ=unbound-fuzzme.lo
|
||||
+FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
+$(COMPAT_OBJ)
|
||||
CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
|
||||
CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
|
||||
CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
|
||||
rsrc_unbound_checkconf.o
|
||||
|
||||
ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
+ $(FUZZME_SRC) \
|
||||
$(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
|
||||
$(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
|
||||
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
|
||||
@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
|
||||
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
|
||||
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
|
||||
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
|
||||
+ $(FUZZME_OBJ) \
|
||||
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
|
||||
$(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
|
||||
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
|
||||
@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL
|
||||
|
||||
all: $(COMMON_OBJ) $(ALLTARGET)
|
||||
|
||||
-alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET)
|
||||
+alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET)
|
||||
|
||||
# compat with BSD make, register suffix, and an implicit rule to actualise it.
|
||||
.SUFFIXES: .lo
|
||||
@@ -325,6 +331,9 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
|
||||
unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
+unbound-fuzzme$(EXEEXT): $(FUZZME_OBJ_LINK) libunbound.la
|
||||
+ $(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
+
|
||||
unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
|
||||
$(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
|
||||
|
||||
@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d *.lo *~ tags
|
||||
- rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
|
||||
+ rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
|
||||
rm -f $(ALL_SRC:.c=.lint)
|
||||
rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
|
||||
rm -rf autom4te.cache .libs build doc/html doc/xml
|
||||
@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
|
||||
$(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
$(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
|
||||
$(srcdir)/validator/val_neg.h
|
||||
+unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \
|
||||
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
|
||||
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
|
||||
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
|
||||
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
|
||||
+ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
|
||||
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
|
||||
+ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
|
||||
unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
|
||||
$(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
|
||||
$(srcdir)/daemon/remote.h \
|
||||
diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c
|
||||
new file mode 100644
|
||||
index 00000000..74ae5204
|
||||
--- /dev/null
|
||||
+++ b/smallapp/unbound-fuzzme.c
|
||||
@@ -0,0 +1,38 @@
|
||||
+/*
|
||||
+ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing).
|
||||
+ *
|
||||
+ */
|
||||
+#include "config.h"
|
||||
+#include "util/regional.h"
|
||||
+#include "util/fptr_wlist.h"
|
||||
+#include "sldns/sbuffer.h"
|
||||
+
|
||||
+#define SZ 10000
|
||||
+
|
||||
+int main() {
|
||||
+ char buffer[SZ];
|
||||
+ size_t n_read = fread(buffer, 1, SZ, stdin);
|
||||
+ if (n_read == SZ) {
|
||||
+ printf("input too big\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ sldns_buffer *pkt = sldns_buffer_new(n_read);
|
||||
+ sldns_buffer_init_frm_data(pkt, buffer, n_read);
|
||||
+
|
||||
+ struct regional *region = regional_create();
|
||||
+
|
||||
+ struct msg_parse* prs;
|
||||
+ struct edns_data edns;
|
||||
+ prs = (struct msg_parse*)malloc(sizeof(struct msg_parse));
|
||||
+ if(!prs) {
|
||||
+ printf("out of memory on incoming message\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+ memset(prs, 0, sizeof(*prs));
|
||||
+ memset(&edns, 0, sizeof(edns));
|
||||
+ sldns_buffer_set_position(pkt, 0);
|
||||
+ if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) {
|
||||
+ printf("parse error\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import hashlib
|
||||
import sys
|
||||
import struct
|
||||
import socket
|
||||
import time
|
||||
from optparse import OptionParser
|
||||
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
|
||||
def _calc_hashkey(qname, secret, qtype):
|
||||
qclass = 'IN' # CLASS is fixed for simplicity
|
||||
hobj = hashlib.sha256()
|
||||
hobj.update(dns.name.from_text(qname).to_wire())
|
||||
hobj.update(struct.pack('HH',
|
||||
socket.htons(dns.rdatatype.from_text(qtype)),
|
||||
socket.htons(dns.rdataclass.from_text(qclass))))
|
||||
hobj.update(secret)
|
||||
return hobj.hexdigest().upper()
|
||||
|
||||
def _redis_get(options, key):
|
||||
import redis
|
||||
return redis.Redis(options.address, int(options.port)).get(key)
|
||||
|
||||
def _dump_value(options, qname, key, value):
|
||||
print(';; query=%s/IN/%s' % (qname, options.qtype))
|
||||
print(';; key=%s' % key)
|
||||
if value is None:
|
||||
print(';; no value')
|
||||
return
|
||||
if len(value) < 16:
|
||||
print(';; broken value, short length: %d' % len(value))
|
||||
return
|
||||
now = int(time.time())
|
||||
timestamp = struct.unpack('!Q', value[-16:-8])[0]
|
||||
expire = struct.unpack('!Q', value[-8:])[0]
|
||||
print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
|
||||
(now, timestamp, expire, max(expire - now, 0)))
|
||||
print(dns.message.from_wire(value[:-16]))
|
||||
|
||||
def main():
|
||||
parser = OptionParser(usage='usage: %prog [options] query_name')
|
||||
parser.add_option("-a", "--address", dest="address", action="store",
|
||||
default='127.0.0.1', help="backend-server address",
|
||||
metavar='ADDRESS')
|
||||
parser.add_option("-b", "--backend", dest="backend", action="store",
|
||||
default='redis', help="backend name",
|
||||
metavar='BACKEND')
|
||||
parser.add_option("-p", "--port", dest="port", action="store",
|
||||
default='6379', help="backend-server port",
|
||||
metavar='PORT')
|
||||
parser.add_option("-s", "--secret", dest="secret", action="store",
|
||||
default='default', help="secret seed", metavar='SECRET')
|
||||
parser.add_option("-t", "--qtype", dest="qtype", action="store",
|
||||
default='A', help="query RR type", metavar='QTYPE')
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
if len(args) < 1:
|
||||
parser.error('qname is missing')
|
||||
if options.backend == 'redis':
|
||||
get_func = _redis_get
|
||||
else:
|
||||
raise Exception('unknown backend name: %s\n' % options.backend)
|
||||
key = _calc_hashkey(args[0], options.secret, options.qtype)
|
||||
value = get_func(options, key)
|
||||
_dump_value(options, args[0], key, value)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except Exception as e:
|
||||
sys.stderr.write('%s\n' % e)
|
||||
exit(1)
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 $?
|
||||
@@ -1,88 +0,0 @@
|
||||
; 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.
|
||||
;
|
||||
;
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network-online.target
|
||||
Before=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_RAW
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -1,6 +0,0 @@
|
||||
[Socket]
|
||||
ListenDatagram=127.0.0.1:1153
|
||||
ListenStream=127.0.0.1:1153
|
||||
# ListenStream=@UNBOUND_RUN_DIR@/control
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
+7
-13
@@ -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
|
||||
|
||||
@@ -18,6 +18,7 @@ Source2: unbound.conf
|
||||
Source3: unbound.munin
|
||||
Source4: unbound_munin_
|
||||
Source5: root.key
|
||||
Source6: dlv.isc.org.key
|
||||
Patch1: unbound-1.2-glob.patch
|
||||
|
||||
Group: System Environment/Daemons
|
||||
@@ -139,6 +140,7 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%attr(0755,root,root) %dir %{_sysconfdir}/%{name}
|
||||
%ghost %attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name}
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/unbound.conf
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/dlv.isc.org.key
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/%{name}/root.key
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*/*
|
||||
@@ -176,6 +178,11 @@ exit 0
|
||||
|
||||
%post
|
||||
/sbin/chkconfig --add %{name}
|
||||
# dnssec-conf used to contain our DLV key, but now we include it via unbound
|
||||
# If unbound had previously been configured with dnssec-configure, we need
|
||||
# to migrate the location of the DLV key file (to keep DLV enabled, and because
|
||||
# unbound won't start with a bad location for a DLV key file.
|
||||
sed -i "s:/etc/pki/dnssec-keys[/]*dlv:/etc/unbound:" %{_sysconfdir}/unbound/unbound.conf
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
|
||||
@@ -273,7 +280,7 @@ fi
|
||||
- Change make/configure lines to attempt to fix -lphtread linking issue
|
||||
|
||||
* Thu Feb 18 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-2
|
||||
- Removed dependency for dnssec-conf
|
||||
- Removed dependancy for dnssec-conf
|
||||
- Added ISC DLV key (formerly in dnssec-conf)
|
||||
- Fixup old DLV locations in unbound.conf file via %%post
|
||||
- Fix parent child disagreement handling and no-ipv6 present [svn r1953]
|
||||
@@ -312,7 +319,7 @@ fi
|
||||
- Re-enabled glob.patch
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-7
|
||||
- unbound-iterator.patch was not committed
|
||||
- unbound-iterator.patch was not commited
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-6
|
||||
- Fix for https://bugzilla.redhat.com/show_bug.cgi?id=499793
|
||||
@@ -338,11 +345,11 @@ fi
|
||||
|
||||
* Wed Jan 14 2009 Paul Wouters <paul@xelerance.com - 1.2.0-1
|
||||
- Updated to 1.2.0
|
||||
- Added dependency on minimum SSL for CVE-2008-5077
|
||||
- Added dependency on bc for unbound-munin
|
||||
- Added dependancy on minimum SSL for CVE-2008-5077
|
||||
- Added dependancy on bc for unbound-munin
|
||||
- Added minimum requirement of libevent 1.4.5. Crashes with older versions
|
||||
(note: libevent is stale in EL-4 and not in EL-5, needs fixing there)
|
||||
- Removed dependency on selinux-policy (will get used when available)
|
||||
- Removed dependancy on selinux-policy (will get used when available)
|
||||
- Enable options as per draft-wijngaards-dnsext-resolver-side-mitigation-00.txt
|
||||
- Enable unwanted-reply-threshold to mitigate against a Kaminsky attack
|
||||
- Enable val-clean-additional to drop addition unsigned data from signed
|
||||
@@ -423,7 +430,7 @@ fi
|
||||
- Build against ldns-1.3.0
|
||||
|
||||
* Wed May 21 2008 Paul Wouters <paul@xelerance.com> - 1.0.0-1
|
||||
- Split of -devel package, fixed dependencies, make rpmlint happy
|
||||
- Split of -devel package, fixed dependancies, make rpmlint happy
|
||||
|
||||
* Thu Apr 25 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 0.12
|
||||
- Using parts from ports collection entry by Jaap Akkerhuis.
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
@echo off
|
||||
rem --------------------------------------------------------------
|
||||
rem -- DNS cache save/load script
|
||||
rem --
|
||||
rem -- Version 1.2
|
||||
rem -- By Yuri Voinov (c) 2014
|
||||
rem --------------------------------------------------------------
|
||||
|
||||
rem Variables
|
||||
set prefix="C:\Program Files (x86)"
|
||||
set program_path=%prefix%\Unbound
|
||||
set uc=%program_path%\unbound-control.exe
|
||||
set fname="unbound_cache.dmp"
|
||||
|
||||
rem Check Unbound installed
|
||||
if exist %uc% goto start
|
||||
echo Unbound control not found. Exiting...
|
||||
exit 1
|
||||
|
||||
:start
|
||||
|
||||
rem arg1 - command (optional)
|
||||
rem arg2 - file name (optional)
|
||||
set arg1=%1
|
||||
set arg2=%2
|
||||
|
||||
if /I "%arg1%" == "-h" goto help
|
||||
|
||||
if "%arg1%" == "" (
|
||||
echo Loading cache from %program_path%\%fname%
|
||||
dir /a %program_path%\%fname%
|
||||
type %program_path%\%fname%|%uc% load_cache
|
||||
goto end
|
||||
)
|
||||
|
||||
if defined %arg2% (goto Not_Defined) else (goto Defined)
|
||||
|
||||
rem If file not specified; use default dump file
|
||||
:Not_defined
|
||||
if /I "%arg1%" == "-s" (
|
||||
echo Saving cache to %program_path%\%fname%
|
||||
%uc% dump_cache>%program_path%\%fname%
|
||||
dir /a %program_path%\%fname%
|
||||
echo ok
|
||||
goto end
|
||||
)
|
||||
|
||||
if /I "%arg1%" == "-l" (
|
||||
echo Loading cache from %program_path%\%fname%
|
||||
dir /a %program_path%\%fname%
|
||||
type %program_path%\%fname%|%uc% load_cache
|
||||
goto end
|
||||
)
|
||||
|
||||
if /I "%arg1%" == "-r" (
|
||||
echo Saving cache to %program_path%\%fname%
|
||||
dir /a %program_path%\%fname%
|
||||
%uc% dump_cache>%program_path%\%fname%
|
||||
echo ok
|
||||
echo Loading cache from %program_path%\%fname%
|
||||
type %program_path%\%fname%|%uc% load_cache
|
||||
goto end
|
||||
)
|
||||
|
||||
rem If file name specified; use this filename
|
||||
:Defined
|
||||
if /I "%arg1%" == "-s" (
|
||||
echo Saving cache to %arg2%
|
||||
%uc% dump_cache>%arg2%
|
||||
dir /a %arg2%
|
||||
echo ok
|
||||
goto end
|
||||
)
|
||||
|
||||
if /I "%arg1%" == "-l" (
|
||||
echo Loading cache from %arg2%
|
||||
dir /a %arg2%
|
||||
type %arg2%|%uc% load_cache
|
||||
goto end
|
||||
)
|
||||
|
||||
if /I "%arg1%" == "-r" (
|
||||
echo Saving cache to %arg2%
|
||||
dir /a %arg2%
|
||||
%uc% dump_cache>%arg2%
|
||||
echo ok
|
||||
echo Loading cache from %arg2%
|
||||
type %arg2%|%uc% load_cache
|
||||
goto end
|
||||
)
|
||||
|
||||
:help
|
||||
echo Usage: unbound_cache.cmd [-s] or [-l] or [-r] or [-h] [filename]
|
||||
echo.
|
||||
echo l - Load - default mode. Warming up Unbound DNS cache from saved file. cache-ttl must be high value.
|
||||
echo s - Save - save Unbound DNS cache contents to plain file with domain names.
|
||||
echo r - Reload - reloadind new cache entries and refresh existing cache
|
||||
echo h - this screen.
|
||||
echo filename - file to save/load dumped cache. If not specified, %program_path%\%fname% will be used instead.
|
||||
echo Note: Run without any arguments will be in default mode.
|
||||
echo Also, unbound-control must be configured.
|
||||
exit 1
|
||||
|
||||
:end
|
||||
exit 0
|
||||
@@ -1,174 +0,0 @@
|
||||
#!/sbin/sh
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# -- DNS cache save/load script
|
||||
# --
|
||||
# -- Version 1.2
|
||||
# -- By Yuri Voinov (c) 2006, 2014
|
||||
# --------------------------------------------------------------
|
||||
#
|
||||
# ident "@(#)unbound_cache.sh 1.2 14/10/30 YV"
|
||||
#
|
||||
|
||||
#############
|
||||
# Variables #
|
||||
#############
|
||||
|
||||
# Installation base dir
|
||||
CONF="/etc/opt/csw/unbound"
|
||||
BASE="/opt/csw"
|
||||
|
||||
# Unbound binaries
|
||||
UC="$BASE/sbin/unbound-control"
|
||||
FNAME="unbound_cache.dmp"
|
||||
|
||||
# OS utilities
|
||||
BASENAME=`which basename`
|
||||
CAT=`which cat`
|
||||
CUT=`which cut`
|
||||
ECHO=`which echo`
|
||||
EXPR=`which expr`
|
||||
GETOPT=`which getopt`
|
||||
ID=`which id`
|
||||
LS=`which ls`
|
||||
|
||||
###############
|
||||
# Subroutines #
|
||||
###############
|
||||
|
||||
usage_note ()
|
||||
{
|
||||
# Script usage note
|
||||
$ECHO "Usage: `$BASENAME $0` [-s] or [-l] or [-r] or [-h] [filename]"
|
||||
$ECHO .
|
||||
$ECHO "l - Load - default mode. Warming up Unbound DNS cache from saved file. cache-ttl must be high value."
|
||||
$ECHO "s - Save - save Unbound DNS cache contents to plain file with domain names."
|
||||
$ECHO "r - Reload - reloadind new cache entries and refresh existing cache"
|
||||
$ECHO "h - this screen."
|
||||
$ECHO "filename - file to save/load dumped cache. If not specified, $CONF/$FNAME will be used instead."
|
||||
$ECHO "Note: Run without any arguments will be in default mode."
|
||||
$ECHO " Also, unbound-control must be configured."
|
||||
exit 0
|
||||
}
|
||||
|
||||
root_check ()
|
||||
{
|
||||
if [ ! `$ID | $CUT -f1 -d" "` = "uid=0(root)" ]; then
|
||||
$ECHO "ERROR: You must be super-user to run this script."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_uc ()
|
||||
{
|
||||
if [ ! -f "$UC" ]; then
|
||||
$ECHO .
|
||||
$ECHO "ERROR: $UC not found. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_saved_file ()
|
||||
{
|
||||
filename=$1
|
||||
if [ ! -z "$filename" -a ! -f "$filename" ]; then
|
||||
$ECHO .
|
||||
$ECHO "ERROR: File $filename does not exists. Save it first."
|
||||
exit 1
|
||||
elif [ ! -f "$CONF/$FNAME" ]; then
|
||||
$ECHO .
|
||||
$ECHO "ERROR: File $CONF/$FNAME does not exists. Save it first."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
save_cache ()
|
||||
{
|
||||
# Save unbound cache
|
||||
filename=$1
|
||||
if [ -z "$filename" ]; then
|
||||
$ECHO "Saving cache in $CONF/$FNAME..."
|
||||
$UC dump_cache>$CONF/$FNAME
|
||||
$LS -lh $CONF/$FNAME
|
||||
else
|
||||
$ECHO "Saving cache in $filename..."
|
||||
$UC dump_cache>$filename
|
||||
$LS -lh $filename
|
||||
fi
|
||||
$ECHO "ok"
|
||||
}
|
||||
|
||||
load_cache ()
|
||||
{
|
||||
# Load saved cache contents and warmup cache
|
||||
filename=$1
|
||||
if [ -z "$filename" ]; then
|
||||
$ECHO "Loading cache from saved $CONF/$FNAME..."
|
||||
$LS -lh $CONF/$FNAME
|
||||
check_saved_file $filename
|
||||
$CAT $CONF/$FNAME|$UC load_cache
|
||||
else
|
||||
$ECHO "Loading cache from saved $filename..."
|
||||
$LS -lh $filename
|
||||
check_saved_file $filename
|
||||
$CAT $filename|$UC load_cache
|
||||
fi
|
||||
}
|
||||
|
||||
reload_cache ()
|
||||
{
|
||||
# Reloading and refresh existing cache and saved dump
|
||||
filename=$1
|
||||
save_cache $filename
|
||||
load_cache $filename
|
||||
}
|
||||
|
||||
##############
|
||||
# Main block #
|
||||
##############
|
||||
|
||||
# Root check
|
||||
root_check
|
||||
|
||||
# Check unbound-control
|
||||
check_uc
|
||||
|
||||
# Check command-line arguments
|
||||
if [ "x$*" = "x" ]; then
|
||||
# If arguments list empty,load cache by default
|
||||
load_cache
|
||||
else
|
||||
arg_list=$*
|
||||
# Parse command line
|
||||
set -- `$GETOPT sSlLrRhH: $arg_list` || {
|
||||
usage_note 1>&2
|
||||
}
|
||||
|
||||
# Read arguments
|
||||
for i in $arg_list
|
||||
do
|
||||
case $i in
|
||||
-s | -S) save="1";;
|
||||
-l | -L) save="0";;
|
||||
-r | -R) save="2";;
|
||||
-h | -H | \?) usage_note;;
|
||||
*) shift
|
||||
file=$1
|
||||
break;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Remove trailing --
|
||||
shift `$EXPR $OPTIND - 1`
|
||||
fi
|
||||
|
||||
if [ "$save" = "1" ]; then
|
||||
save_cache $file
|
||||
elif [ "$save" = "0" ]; then
|
||||
load_cache $file
|
||||
elif [ "$save" = "2" ]; then
|
||||
reload_cache $file
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Binary file not shown.
+124
-137
@@ -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
|
||||
@@ -160,7 +150,7 @@ get_state ( ) {
|
||||
fi
|
||||
done
|
||||
# try to get it
|
||||
if echo $$ >$lock ; then : ; else break; fi
|
||||
echo $$ >$lock
|
||||
done
|
||||
# do not refetch if the file exists and only LEE seconds old
|
||||
if test -f $state; then
|
||||
@@ -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
|
||||
@@ -221,7 +210,6 @@ exist_config ( ) {
|
||||
if grep '^'$1'=' $state >/dev/null 2>&1; then
|
||||
echo "$mn.label $2"
|
||||
echo "$mn.min 0"
|
||||
echo "$mn.type ABSOLUTE"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -230,7 +218,6 @@ p_config ( ) {
|
||||
mn=`echo $1 | sed $ABBREV | tr . _`
|
||||
echo $mn.label "$2"
|
||||
echo $mn.min 0
|
||||
echo $mn.type $3
|
||||
}
|
||||
|
||||
if test "$1" = "config" ; then
|
||||
@@ -241,24 +228,19 @@ if test "$1" = "config" ; then
|
||||
hits)
|
||||
echo "graph_title Unbound DNS traffic and cache hits"
|
||||
echo "graph_args --base 1000 -l 0"
|
||||
echo "graph_vlabel queries / \${graph_period}"
|
||||
echo "graph_scale no"
|
||||
echo "graph_category dns"
|
||||
echo "graph_vlabel queries / second"
|
||||
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`"
|
||||
done
|
||||
p_config "total.num.queries" "total queries from clients" "ABSOLUTE"
|
||||
p_config "total.num.cachehits" "cache hits" "ABSOLUTE"
|
||||
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"
|
||||
p_config "total.num.queries" "total queries from clients"
|
||||
p_config "total.num.cachehits" "cache hits"
|
||||
p_config "total.num.prefetch" "cache prefetch"
|
||||
p_config "num.query.tcp" "TCP queries"
|
||||
p_config "num.query.ipv6" "IPv6 queries"
|
||||
p_config "unwanted.queries" "queries that failed acl"
|
||||
p_config "unwanted.replies" "unwanted or unsolicited replies"
|
||||
echo "u_replies.warning $warn"
|
||||
echo "u_replies.critical $crit"
|
||||
echo "graph_info DNS queries to the recursive resolver. The unwanted replies could be innocent duplicate packets, late replies, or spoof threats."
|
||||
@@ -267,152 +249,136 @@ if test "$1" = "config" ; then
|
||||
echo "graph_title Unbound requestlist size"
|
||||
echo "graph_args --base 1000 -l 0"
|
||||
echo "graph_vlabel number of queries"
|
||||
echo "graph_scale no"
|
||||
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"
|
||||
p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space" "GAUGE"
|
||||
echo "graph_category DNS"
|
||||
p_config "total.requestlist.avg" "Average size of queue on insert"
|
||||
p_config "total.requestlist.max" "Max size of queue (in 5 min)"
|
||||
p_config "total.requestlist.overwritten" "Number of queries replaced by new ones"
|
||||
p_config "total.requestlist.exceeded" "Number of queries dropped due to lack of space"
|
||||
echo "graph_info The queries that did not hit the cache and need recursion service take up space in the requestlist. If there are too many queries, first queries get overwritten, and at last resort dropped."
|
||||
;;
|
||||
memory)
|
||||
echo "graph_title Unbound memory usage"
|
||||
echo "graph_args --base 1024 -l 0"
|
||||
echo "graph_vlabel memory used in bytes"
|
||||
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"
|
||||
p_config "mem.mod.validator" "Validator module and key cache memory" "GAUGE"
|
||||
p_config "msg.cache.count" "msg cache count" "GAUGE"
|
||||
p_config "rrset.cache.count" "rrset cache count" "GAUGE"
|
||||
p_config "infra.cache.count" "infra cache count" "GAUGE"
|
||||
p_config "key.cache.count" "key cache count" "GAUGE"
|
||||
echo "graph_category DNS"
|
||||
p_config "mem.total.sbrk" "Total memory"
|
||||
p_config "mem.cache.rrset" "RRset cache memory"
|
||||
p_config "mem.cache.message" "Message cache memory"
|
||||
p_config "mem.mod.iterator" "Iterator module memory"
|
||||
p_config "mem.mod.validator" "Validator module and key cache memory"
|
||||
echo "graph_info The memory used by unbound."
|
||||
;;
|
||||
by_type)
|
||||
echo "graph_title Unbound DNS queries by type"
|
||||
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_vlabel queries / second"
|
||||
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"
|
||||
p_config "$nm" "$tp"
|
||||
done
|
||||
echo "graph_info queries by DNS RR type queried for"
|
||||
;;
|
||||
by_class)
|
||||
echo "graph_title Unbound DNS queries by class"
|
||||
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_vlabel queries / second"
|
||||
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"
|
||||
p_config "$nm" "$tp"
|
||||
done
|
||||
echo "graph_info queries by DNS RR class queried for."
|
||||
;;
|
||||
by_opcode)
|
||||
echo "graph_title Unbound DNS queries by opcode"
|
||||
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_vlabel queries / second"
|
||||
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"
|
||||
p_config "$nm" "$tp"
|
||||
done
|
||||
echo "graph_info queries by opcode in the query packet."
|
||||
;;
|
||||
by_rcode)
|
||||
echo "graph_title Unbound DNS answers by return code"
|
||||
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_vlabel answer packets / second"
|
||||
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"
|
||||
p_config "$nm" "$tp"
|
||||
done
|
||||
p_config "num.answer.secure" "answer secure" "ABSOLUTE"
|
||||
p_config "num.answer.bogus" "answer bogus" "ABSOLUTE"
|
||||
p_config "num.rrset.bogus" "num rrsets marked bogus" "ABSOLUTE"
|
||||
echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per \${graph_period} by the validator"
|
||||
p_config "num.answer.secure" "answer secure"
|
||||
p_config "num.answer.bogus" "answer bogus"
|
||||
p_config "num.rrset.bogus" "num rrsets marked bogus"
|
||||
echo "graph_info answers sorted by return value. rrsets bogus is the number of rrsets marked bogus per second by the validator"
|
||||
;;
|
||||
by_flags)
|
||||
echo "graph_title Unbound DNS incoming queries by flags"
|
||||
echo "graph_args --base 1000 -l 0"
|
||||
echo "graph_vlabel queries / \${graph_period}"
|
||||
echo "graph_scale no"
|
||||
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"
|
||||
p_config "num.query.flags.RD" "RD (recursion desired) flag" "ABSOLUTE"
|
||||
p_config "num.query.flags.RA" "RA (rec avail) flag" "ABSOLUTE"
|
||||
p_config "num.query.flags.Z" "Z (zero) flag" "ABSOLUTE"
|
||||
p_config "num.query.flags.AD" "AD (auth data) flag" "ABSOLUTE"
|
||||
p_config "num.query.flags.CD" "CD (check disabled) flag" "ABSOLUTE"
|
||||
p_config "num.query.edns.present" "EDNS OPT present" "ABSOLUTE"
|
||||
p_config "num.query.edns.DO" "DO (DNSSEC OK) flag" "ABSOLUTE"
|
||||
echo "graph_vlabel queries / second"
|
||||
echo "graph_category DNS"
|
||||
p_config "num.query.flags.QR" "QR (query reply) flag"
|
||||
p_config "num.query.flags.AA" "AA (auth answer) flag"
|
||||
p_config "num.query.flags.TC" "TC (truncated) flag"
|
||||
p_config "num.query.flags.RD" "RD (recursion desired) flag"
|
||||
p_config "num.query.flags.RA" "RA (rec avail) flag"
|
||||
p_config "num.query.flags.Z" "Z (zero) flag"
|
||||
p_config "num.query.flags.AD" "AD (auth data) flag"
|
||||
p_config "num.query.flags.CD" "CD (check disabled) flag"
|
||||
p_config "num.query.edns.present" "EDNS OPT present"
|
||||
p_config "num.query.edns.DO" "DO (DNSSEC OK) flag"
|
||||
echo "graph_info This graphs plots the flags inside incoming queries. For example, if QR, AA, TC, RA, Z flags are set, the query can be rejected. RD, AD, CD and DO are legitimately set by some software."
|
||||
;;
|
||||
histogram)
|
||||
echo "graph_title Unbound DNS histogram of reply time"
|
||||
echo "graph_args --base 1000 -l 0"
|
||||
echo "graph_vlabel queries / \${graph_period}"
|
||||
echo "graph_scale no"
|
||||
echo "graph_category dns"
|
||||
echo "graph_vlabel queries / second"
|
||||
echo "graph_category DNS"
|
||||
echo hcache.label "cache hits"
|
||||
echo hcache.min 0
|
||||
echo hcache.type ABSOLUTE
|
||||
echo hcache.draw AREA
|
||||
echo hcache.colour 999999
|
||||
echo h64ms.label "0 msec - 66 msec"
|
||||
echo h64ms.min 0
|
||||
echo h64ms.type ABSOLUTE
|
||||
echo h64ms.draw STACK
|
||||
echo h64ms.colour 0000FF
|
||||
echo h128ms.label "66 msec - 131 msec"
|
||||
echo h128ms.min 0
|
||||
echo h128ms.type ABSOLUTE
|
||||
echo h128ms.colour 1F00DF
|
||||
echo h128ms.draw STACK
|
||||
echo h256ms.label "131 msec - 262 msec"
|
||||
echo h256ms.min 0
|
||||
echo h256ms.type ABSOLUTE
|
||||
echo h256ms.draw STACK
|
||||
echo h256ms.colour 3F00BF
|
||||
echo h512ms.label "262 msec - 524 msec"
|
||||
echo h512ms.min 0
|
||||
echo h512ms.type ABSOLUTE
|
||||
echo h512ms.draw STACK
|
||||
echo h512ms.colour 5F009F
|
||||
echo h1s.label "524 msec - 1 sec"
|
||||
echo h1s.min 0
|
||||
echo h1s.type ABSOLUTE
|
||||
echo h1s.draw STACK
|
||||
echo h1s.colour 7F007F
|
||||
echo h2s.label "1 sec - 2 sec"
|
||||
echo h2s.min 0
|
||||
echo h2s.type ABSOLUTE
|
||||
echo h2s.draw STACK
|
||||
echo h2s.colour 9F005F
|
||||
echo h4s.label "2 sec - 4 sec"
|
||||
echo h4s.min 0
|
||||
echo h4s.type ABSOLUTE
|
||||
echo h4s.draw STACK
|
||||
echo h4s.colour BF003F
|
||||
echo h8s.label "4 sec - 8 sec"
|
||||
echo h8s.min 0
|
||||
echo h8s.type ABSOLUTE
|
||||
echo h8s.draw STACK
|
||||
echo h8s.colour DF001F
|
||||
echo h16s.label "8 sec - ..."
|
||||
echo h16s.min 0
|
||||
echo h16s.type ABSOLUTE
|
||||
echo h16s.draw STACK
|
||||
echo h16s.colour FF0000
|
||||
echo "graph_info Histogram of the reply times for queries."
|
||||
@@ -433,6 +399,20 @@ if test $value = 0 || test $value = "0.000000"; then
|
||||
fi
|
||||
elapsed="$value"
|
||||
|
||||
# print value for $1 / elapsed
|
||||
print_qps ( ) {
|
||||
mn=`echo $1 | sed $ABBREV | tr . _`
|
||||
get_value $1
|
||||
echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
|
||||
}
|
||||
|
||||
# print qps if line already found in $2
|
||||
print_qps_line ( ) {
|
||||
mn=`echo $1 | sed $ABBREV | tr . _`
|
||||
value="`echo $2 | sed -e 's/^.*=//'`"
|
||||
echo "$mn.value" `echo scale=6';' $value / $elapsed | bc `
|
||||
}
|
||||
|
||||
# print value for $1
|
||||
print_value ( ) {
|
||||
mn=`echo $1 | sed $ABBREV | tr . _`
|
||||
@@ -440,24 +420,14 @@ print_value ( ) {
|
||||
echo "$mn.value" $value
|
||||
}
|
||||
|
||||
# print value if line already found in $2
|
||||
print_value_line ( ) {
|
||||
mn=`echo $1 | sed $ABBREV | tr . _`
|
||||
value="`echo $2 | sed -e 's/^.*=//'`"
|
||||
echo "$mn.value" $value
|
||||
}
|
||||
|
||||
|
||||
case $id in
|
||||
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 \
|
||||
unwanted.replies; do
|
||||
num.query.ipv6 unwanted.queries unwanted.replies; do
|
||||
if grep "^"$x"=" $state >/dev/null 2>&1; then
|
||||
print_value $x
|
||||
print_qps $x
|
||||
fi
|
||||
done
|
||||
;;
|
||||
@@ -468,43 +438,60 @@ queue)
|
||||
done
|
||||
;;
|
||||
memory)
|
||||
for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
|
||||
mem.mod.validator msg.cache.count rrset.cache.count \
|
||||
infra.cache.count key.cache.count; do
|
||||
mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
|
||||
get_value 'mem.total.sbrk'
|
||||
if test $value -eq 0; then
|
||||
chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
|
||||
pidf=`$chk -o pidfile $conf 2>&1`
|
||||
pid=`cat $pidf 2>&1`
|
||||
value=`ps -p "$pid" -o rss= 2>&1`
|
||||
if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
|
||||
value=`expr $value \* 1024`
|
||||
else
|
||||
value=0
|
||||
fi
|
||||
fi
|
||||
echo "$mn.value" $value
|
||||
for x in mem.cache.rrset mem.cache.message \
|
||||
mem.mod.iterator mem.mod.validator; do
|
||||
print_value $x
|
||||
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_qps_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_qps_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_qps_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_qps_line $nm $x
|
||||
done
|
||||
print_value "num.answer.secure"
|
||||
print_value "num.answer.bogus"
|
||||
print_value "num.rrset.bogus"
|
||||
print_qps "num.answer.secure"
|
||||
print_qps "num.answer.bogus"
|
||||
print_qps "num.rrset.bogus"
|
||||
;;
|
||||
by_flags)
|
||||
for x in num.query.flags.QR num.query.flags.AA num.query.flags.TC num.query.flags.RD num.query.flags.RA num.query.flags.Z num.query.flags.AD num.query.flags.CD num.query.edns.present num.query.edns.DO; do
|
||||
print_value $x
|
||||
print_qps $x
|
||||
done
|
||||
;;
|
||||
histogram)
|
||||
get_value total.num.cachehits
|
||||
echo hcache.value $value
|
||||
echo hcache.value `echo scale=6';' $value / $elapsed | bc `
|
||||
r=0
|
||||
for x in histogram.000000.000000.to.000000.000001 \
|
||||
histogram.000000.000001.to.000000.000002 \
|
||||
@@ -526,21 +513,21 @@ histogram)
|
||||
get_value $x
|
||||
r=`expr $r + $value`
|
||||
done
|
||||
echo h64ms.value $r
|
||||
echo h64ms.value `echo scale=6';' $r / $elapsed | bc `
|
||||
get_value histogram.000000.065536.to.000000.131072
|
||||
echo h128ms.value $value
|
||||
echo h128ms.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000000.131072.to.000000.262144
|
||||
echo h256ms.value $value
|
||||
echo h256ms.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000000.262144.to.000000.524288
|
||||
echo h512ms.value $value
|
||||
echo h512ms.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000000.524288.to.000001.000000
|
||||
echo h1s.value $value
|
||||
echo h1s.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000001.000000.to.000002.000000
|
||||
echo h2s.value $value
|
||||
echo h2s.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000002.000000.to.000004.000000
|
||||
echo h4s.value $value
|
||||
echo h4s.value `echo scale=6';' $value / $elapsed | bc `
|
||||
get_value histogram.000004.000000.to.000008.000000
|
||||
echo h8s.value $value
|
||||
echo h8s.value `echo scale=6';' $value / $elapsed | bc `
|
||||
r=0
|
||||
for x in histogram.000008.000000.to.000016.000000 \
|
||||
histogram.000016.000000.to.000032.000000 \
|
||||
@@ -561,6 +548,6 @@ histogram)
|
||||
get_value $x
|
||||
r=`expr $r + $value`
|
||||
done
|
||||
echo h16s.value $r
|
||||
echo h16s.value `echo scale=6';' $r / $elapsed | bc `
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -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_RAW
|
||||
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.
@@ -0,0 +1,305 @@
|
||||
diff --git a/daemon/remote.c b/daemon/remote.c
|
||||
index a2b2204..b6990f3 100644
|
||||
--- a/daemon/remote.c
|
||||
+++ b/daemon/remote.c
|
||||
@@ -81,6 +81,11 @@
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
+#ifdef HAVE_PWD_H
|
||||
+#include <pwd.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <fcntl.h>
|
||||
+#endif
|
||||
|
||||
/* just for portability */
|
||||
#ifdef SQ
|
||||
@@ -235,7 +240,8 @@ void daemon_remote_delete(struct daemon_remote* rc)
|
||||
* @return false on failure.
|
||||
*/
|
||||
static int
|
||||
-add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||
+add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
+ struct config_file* cfg)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* res;
|
||||
@@ -246,29 +252,74 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err)
|
||||
snprintf(port, sizeof(port), "%d", nr);
|
||||
port[sizeof(port)-1]=0;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
- hints.ai_socktype = SOCK_STREAM;
|
||||
- hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
- if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
||||
-#ifdef USE_WINSOCK
|
||||
- if(!noproto_is_err && r == EAI_NONAME) {
|
||||
- /* tried to lookup the address as name */
|
||||
- return 1; /* return success, but do nothing */
|
||||
+
|
||||
+ if(ip[0] == '/') {
|
||||
+ /* This looks like UNIX socket! */
|
||||
+ fd = create_domain_accept_sock(ip);
|
||||
+/*
|
||||
+ * When unbound starts, it first creates a socket and then
|
||||
+ * drops privs, so the socket is created as root user.
|
||||
+ * This is fine, but we would like to set _unbound user group
|
||||
+ * for this socket, and permissions should be 0660 so only
|
||||
+ * root and _unbound group members can invoke unbound-control.
|
||||
+ * The username used here is the same as username that unbound
|
||||
+ * uses for its worker processes.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Note: this code is an exact copy of code from daemon.c
|
||||
+ * Normally this should be either wrapped into a function,
|
||||
+ * or gui/gid values should be retrieved at config parsing time
|
||||
+ * and then stored in configfile structure.
|
||||
+ * This requires action from unbound developers!
|
||||
+*/
|
||||
+#ifdef HAVE_GETPWNAM
|
||||
+ struct passwd *pwd = NULL;
|
||||
+ uid_t uid;
|
||||
+ gid_t gid;
|
||||
+ /* initialize, but not to 0 (root) */
|
||||
+ memset(&uid, 112, sizeof(uid));
|
||||
+ memset(&gid, 112, sizeof(gid));
|
||||
+ log_assert(cfg);
|
||||
+
|
||||
+ if(cfg->username && cfg->username[0]) {
|
||||
+ if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
+ fatal_exit("user '%s' does not exist.",
|
||||
+ cfg->username);
|
||||
+ uid = pwd->pw_uid;
|
||||
+ gid = pwd->pw_gid;
|
||||
+ endpwent();
|
||||
}
|
||||
+
|
||||
+ chown(ip, 0, gid);
|
||||
+ chmod(ip, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
+#endif
|
||||
+ } else {
|
||||
+ hints.ai_socktype = SOCK_STREAM;
|
||||
+ hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
+ if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
||||
+#ifdef USE_WINSOCK
|
||||
+ if(!noproto_is_err && r == EAI_NONAME) {
|
||||
+ /* tried to lookup the address as name */
|
||||
+ return 1; /* return success, but do nothing */
|
||||
+ }
|
||||
#endif /* USE_WINSOCK */
|
||||
- log_err("control interface %s:%s getaddrinfo: %s %s",
|
||||
- ip?ip:"default", port, gai_strerror(r),
|
||||
+ log_err("control interface %s:%s getaddrinfo: %s %s",
|
||||
+ ip?ip:"default", port, gai_strerror(r),
|
||||
#ifdef EAI_SYSTEM
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):""
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
- return 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* open fd */
|
||||
+ fd = create_tcp_accept_sock(res, 1, &noproto);
|
||||
+ freeaddrinfo(res);
|
||||
}
|
||||
|
||||
- /* open fd */
|
||||
- fd = create_tcp_accept_sock(res, 1, &noproto);
|
||||
- freeaddrinfo(res);
|
||||
if(fd == -1 && noproto) {
|
||||
if(!noproto_is_err)
|
||||
return 1; /* return success, but do nothing */
|
||||
@@ -305,7 +356,7 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
|
||||
if(cfg->control_ifs) {
|
||||
struct config_strlist* p;
|
||||
for(p = cfg->control_ifs; p; p = p->next) {
|
||||
- if(!add_open(p->str, cfg->control_port, &l, 1)) {
|
||||
+ if(!add_open(p->str, cfg->control_port, &l, 1, cfg)) {
|
||||
listening_ports_free(l);
|
||||
return NULL;
|
||||
}
|
||||
@@ -313,12 +364,12 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg)
|
||||
} else {
|
||||
/* defaults */
|
||||
if(cfg->do_ip6 &&
|
||||
- !add_open("::1", cfg->control_port, &l, 0)) {
|
||||
+ !add_open("::1", cfg->control_port, &l, 0, cfg)) {
|
||||
listening_ports_free(l);
|
||||
return NULL;
|
||||
}
|
||||
if(cfg->do_ip4 &&
|
||||
- !add_open("127.0.0.1", cfg->control_port, &l, 1)) {
|
||||
+ !add_open("127.0.0.1", cfg->control_port, &l, 1, cfg)) {
|
||||
listening_ports_free(l);
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c
|
||||
index ea7ec3a..4cb04e2 100644
|
||||
--- a/services/listen_dnsport.c
|
||||
+++ b/services/listen_dnsport.c
|
||||
@@ -55,6 +55,10 @@
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
+#ifndef USE_WINSOCK
|
||||
+#include <sys/un.h>
|
||||
+#endif
|
||||
+
|
||||
/** number of queued TCP connections for listen() */
|
||||
#define TCP_BACKLOG 5
|
||||
|
||||
@@ -376,6 +380,53 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
}
|
||||
|
||||
int
|
||||
+create_domain_accept_sock(char *path) {
|
||||
+ int s;
|
||||
+ struct sockaddr_un unixaddr;
|
||||
+
|
||||
+#ifndef USE_WINSOCK
|
||||
+ unixaddr.sun_len = sizeof(unixaddr);
|
||||
+ unixaddr.sun_family = AF_UNIX;
|
||||
+ strlcpy(unixaddr.sun_path, path, 104);
|
||||
+
|
||||
+ if((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
|
||||
+ log_err("Cannot create UNIX socket %s (%s)",
|
||||
+ path, strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if(unlink(path) && errno != ENOENT) {
|
||||
+ /* The socket already exists and cannot be removed */
|
||||
+ log_err("Cannot remove old UNIX socket %s (%s)",
|
||||
+ path, strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if(bind(s, (struct sockaddr *) &unixaddr,
|
||||
+ sizeof(struct sockaddr_un)) == -1) {
|
||||
+ log_err("Cannot bind UNIX socket %s (%s)",
|
||||
+ path, strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if(!fd_set_nonblock(s)) {
|
||||
+ log_err("Cannot set non-blocking mode");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if(listen(s, TCP_BACKLOG) == -1) {
|
||||
+ log_err("can't listen: %s", strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return s;
|
||||
+#else
|
||||
+ log_err("UNIX sockets are not supported");
|
||||
+ return -1;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
|
||||
{
|
||||
int s;
|
||||
diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c
|
||||
index a872f92..10631fd 100644
|
||||
--- a/smallapp/unbound-control.c
|
||||
+++ b/smallapp/unbound-control.c
|
||||
@@ -59,6 +59,8 @@
|
||||
#include "util/locks.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
+#include <sys/un.h>
|
||||
+
|
||||
/** Give unbound-control usage, and exit (1). */
|
||||
static void
|
||||
usage()
|
||||
@@ -158,6 +160,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
+ int addrfamily = 0;
|
||||
int fd;
|
||||
/* use svr or the first config entry */
|
||||
if(!svr) {
|
||||
@@ -176,12 +179,21 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
||||
if(strchr(svr, '@')) {
|
||||
if(!extstrtoaddr(svr, &addr, &addrlen))
|
||||
fatal_exit("could not parse IP@port: %s", svr);
|
||||
+ } else if(svr[0] == '/') {
|
||||
+ struct sockaddr_un* unixsock = (struct sockaddr_un *) &addr;
|
||||
+ unixsock->sun_family = AF_UNIX;
|
||||
+ unixsock->sun_len = sizeof(unixsock);
|
||||
+ strlcpy(unixsock->sun_path, svr, 104);
|
||||
+ addrlen = sizeof(struct sockaddr_un);
|
||||
+ addrfamily = AF_UNIX;
|
||||
} else {
|
||||
if(!ipstrtoaddr(svr, cfg->control_port, &addr, &addrlen))
|
||||
fatal_exit("could not parse IP: %s", svr);
|
||||
}
|
||||
- fd = socket(addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET,
|
||||
- SOCK_STREAM, 0);
|
||||
+
|
||||
+ if(addrfamily != AF_UNIX)
|
||||
+ addrfamily = addr_is_ip6(&addr, addrlen)?AF_INET6:AF_INET;
|
||||
+ fd = socket(addrfamily, SOCK_STREAM, 0);
|
||||
if(fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
diff --git a/util/net_help.c b/util/net_help.c
|
||||
index b3136a3..5b5b4a3 100644
|
||||
--- a/util/net_help.c
|
||||
+++ b/util/net_help.c
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "util/module.h"
|
||||
#include "util/regional.h"
|
||||
#include <fcntl.h>
|
||||
+#include <sys/un.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
@@ -135,7 +136,7 @@ log_addr(enum verbosity_value v, const char* str,
|
||||
{
|
||||
uint16_t port;
|
||||
const char* family = "unknown";
|
||||
- char dest[100];
|
||||
+ char dest[108];
|
||||
int af = (int)((struct sockaddr_in*)addr)->sin_family;
|
||||
void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
|
||||
if(verbosity < v)
|
||||
@@ -148,15 +149,23 @@ log_addr(enum verbosity_value v, const char* str,
|
||||
case AF_UNIX: family="unix"; break;
|
||||
default: break;
|
||||
}
|
||||
- if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
||||
- strncpy(dest, "(inet_ntop error)", sizeof(dest));
|
||||
+
|
||||
+ if(af != AF_UNIX) {
|
||||
+ if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
|
||||
+ strncpy(dest, "(inet_ntop error)", sizeof(dest));
|
||||
+ }
|
||||
+ dest[sizeof(dest)-1] = 0;
|
||||
+ port = ntohs(((struct sockaddr_in*)addr)->sin_port);
|
||||
+ if(verbosity >= 4)
|
||||
+ verbose(v, "%s %s %s port %d (len %d)", str, family,
|
||||
+ dest, (int)port, (int)addrlen);
|
||||
+ else verbose(v, "%s %s port %d", str, dest, (int)port);
|
||||
+ } else {
|
||||
+ struct sockaddr_un* unixsock;
|
||||
+ unixsock = (struct sockaddr_un *) addr;
|
||||
+ strlcpy(dest, unixsock->sun_path, sizeof(dest));
|
||||
+ verbose(v, "%s %s %s", str, family, dest);
|
||||
}
|
||||
- dest[sizeof(dest)-1] = 0;
|
||||
- port = ntohs(((struct sockaddr_in*)addr)->sin_port);
|
||||
- if(verbosity >= 4)
|
||||
- verbose(v, "%s %s %s port %d (len %d)", str, family, dest,
|
||||
- (int)port, (int)addrlen);
|
||||
- else verbose(v, "%s %s port %d", str, dest, (int)port);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1,153 +0,0 @@
|
||||
@echo off
|
||||
|
||||
rem --------------------------------------------------------------
|
||||
rem -- Warm up DNS cache script by your own MRU domains or from
|
||||
rem -- file when it specified as script argument.
|
||||
rem --
|
||||
rem -- Version 1.1
|
||||
rem -- By Yuri Voinov (c) 2014
|
||||
rem --------------------------------------------------------------
|
||||
|
||||
rem DNS host address
|
||||
set address="127.0.0.1"
|
||||
|
||||
rem Check dig installed
|
||||
for /f "delims=" %%a in ('where dig') do @set dig=%%a
|
||||
if /I "%dig%"=="" echo Dig not found. If installed, add path to PATH environment variable. & exit 1
|
||||
echo Dig found: %dig%
|
||||
|
||||
set arg=%1%
|
||||
|
||||
if defined %arg% (goto builtin) else (goto from_file)
|
||||
|
||||
:builtin
|
||||
echo Warming up cache by MRU domains...
|
||||
for %%a in (
|
||||
2gis.ru
|
||||
admir.kz
|
||||
adobe.com
|
||||
agent.mail.ru
|
||||
aimp.ru
|
||||
akamai.com
|
||||
akamai.net
|
||||
almaty.tele2.kz
|
||||
aol.com
|
||||
apple.com
|
||||
arin.com
|
||||
artlebedev.ru
|
||||
auto.mail.ru
|
||||
beeline.kz
|
||||
bing.com
|
||||
blogspot.com
|
||||
comodo.com
|
||||
dnscrypt.org
|
||||
drive.google.com
|
||||
drive.mail.ru
|
||||
facebook.com
|
||||
farmanager.com
|
||||
fb.com
|
||||
firefox.com
|
||||
forum.farmanager.com
|
||||
gazeta.ru
|
||||
getsharex.com
|
||||
gismeteo.ru
|
||||
google.com
|
||||
google.kz
|
||||
google.ru
|
||||
googlevideo.com
|
||||
goto.kz
|
||||
iana.org
|
||||
icq.com
|
||||
imap.mail.ru
|
||||
instagram.com
|
||||
intel.com
|
||||
irr.kz
|
||||
java.com
|
||||
kaspersky.com
|
||||
kaspersky.ru
|
||||
kcell.kz
|
||||
krisha.kz
|
||||
lady.mail.ru
|
||||
lenta.ru
|
||||
libreoffice.org
|
||||
linkedin.com
|
||||
livejournal.com
|
||||
mail.google.com
|
||||
mail.ru
|
||||
microsoft.com
|
||||
mozilla.org
|
||||
mra.mail.ru
|
||||
munin-monitoring.org
|
||||
my.mail.ru
|
||||
news.bbcimg.co.uk
|
||||
news.mail.ru
|
||||
newsimg.bbc.net.uk
|
||||
nvidia.com
|
||||
odnoklassniki.ru
|
||||
ok.ru
|
||||
opencsw.org
|
||||
opendns.com
|
||||
opendns.org
|
||||
opennet.ru
|
||||
opera.com
|
||||
oracle.com
|
||||
peerbet.ru
|
||||
piriform.com
|
||||
plugring.farmanager.com
|
||||
privoxy.org
|
||||
qip.ru
|
||||
raidcall.com
|
||||
rambler.ru
|
||||
reddit.com
|
||||
ru.wikipedia.org
|
||||
shallalist.de
|
||||
skype.com
|
||||
snob.ru
|
||||
squid-cache.org
|
||||
squidclamav.darold.net
|
||||
squidguard.org
|
||||
ssl.comodo.com
|
||||
ssl.verisign.com
|
||||
symantec.com
|
||||
symantecliveupdate.com
|
||||
tele2.kz
|
||||
tengrinews.kz
|
||||
thunderbird.com
|
||||
torproject.org
|
||||
torstatus.blutmagie.de
|
||||
translate.google.com
|
||||
unbound.net
|
||||
verisign.com
|
||||
vk.com
|
||||
vk.me
|
||||
vk.ru
|
||||
vkontakte.com
|
||||
vkontakte.ru
|
||||
vlc.org
|
||||
watsapp.net
|
||||
weather.mail.ru
|
||||
windowsupdate.com
|
||||
www.baidu.com
|
||||
www.bbc.co.uk
|
||||
www.internic.net
|
||||
www.opennet.ru
|
||||
www.topgear.com
|
||||
ya.ru
|
||||
yahoo.com
|
||||
yandex.com
|
||||
yandex.ru
|
||||
youtube.com
|
||||
ytimg.com
|
||||
) do "%dig%" %%a @%address% 1>nul 2>nul
|
||||
goto end
|
||||
|
||||
:from_file
|
||||
echo Warming up cache from %1% file...
|
||||
%dig% -f %arg% @%address% 1>nul 2>nul
|
||||
|
||||
:end
|
||||
echo Saving cache...
|
||||
if exist unbound_cache.cmd unbound_cache.cmd -s
|
||||
echo Done.
|
||||
|
||||
exit 0
|
||||
@@ -1,150 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# --------------------------------------------------------------
|
||||
# -- Warm up DNS cache script by your own MRU domains or from
|
||||
# -- file when it specified as script argument.
|
||||
# --
|
||||
# -- Version 1.1
|
||||
# -- By Yuri Voinov (c) 2014
|
||||
# --------------------------------------------------------------
|
||||
|
||||
# Default DNS host address
|
||||
address="127.0.0.1"
|
||||
|
||||
cat=`which cat`
|
||||
dig=`which dig`
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Warming up cache by MRU domains..."
|
||||
$dig -f - @$address >/dev/null 2>&1 <<EOT
|
||||
2gis.ru
|
||||
admir.kz
|
||||
adobe.com
|
||||
agent.mail.ru
|
||||
aimp.ru
|
||||
akamai.com
|
||||
akamai.net
|
||||
almaty.tele2.kz
|
||||
aol.com
|
||||
apple.com
|
||||
arin.com
|
||||
artlebedev.ru
|
||||
auto.mail.ru
|
||||
beeline.kz
|
||||
bing.com
|
||||
blogspot.com
|
||||
clamav.net
|
||||
comodo.com
|
||||
dnscrypt.org
|
||||
drive.google.com
|
||||
drive.mail.ru
|
||||
facebook.com
|
||||
farmanager.com
|
||||
fb.com
|
||||
firefox.com
|
||||
forum.farmanager.com
|
||||
gazeta.ru
|
||||
getsharex.com
|
||||
gismeteo.ru
|
||||
google.com
|
||||
google.kz
|
||||
google.ru
|
||||
googlevideo.com
|
||||
goto.kz
|
||||
iana.org
|
||||
icq.com
|
||||
imap.mail.ru
|
||||
instagram.com
|
||||
instagram.com
|
||||
intel.com
|
||||
irr.kz
|
||||
java.com
|
||||
kaspersky.com
|
||||
kaspersky.ru
|
||||
kcell.kz
|
||||
krisha.kz
|
||||
lady.mail.ru
|
||||
lenta.ru
|
||||
libreoffice.org
|
||||
linkedin.com
|
||||
livejournal.com
|
||||
mail.google.com
|
||||
mail.ru
|
||||
microsoft.com
|
||||
mozilla.org
|
||||
mra.mail.ru
|
||||
munin-monitoring.org
|
||||
my.mail.ru
|
||||
news.bbcimg.co.uk
|
||||
news.mail.ru
|
||||
newsimg.bbc.net.uk
|
||||
nvidia.com
|
||||
odnoklassniki.ru
|
||||
ok.ru
|
||||
opencsw.org
|
||||
opendns.com
|
||||
opendns.org
|
||||
opennet.ru
|
||||
opera.com
|
||||
oracle.com
|
||||
peerbet.ru
|
||||
piriform.com
|
||||
plugring.farmanager.com
|
||||
privoxy.org
|
||||
qip.ru
|
||||
raidcall.com
|
||||
rambler.ru
|
||||
reddit.com
|
||||
ru.wikipedia.org
|
||||
shallalist.de
|
||||
skype.com
|
||||
snob.ru
|
||||
squid-cache.org
|
||||
squidclamav.darold.net
|
||||
squidguard.org
|
||||
ssl.comodo.com
|
||||
ssl.verisign.com
|
||||
symantec.com
|
||||
symantecliveupdate.com
|
||||
tele2.kz
|
||||
tengrinews.kz
|
||||
thunderbird.com
|
||||
torproject.org
|
||||
torstatus.blutmagie.de
|
||||
translate.google.com
|
||||
unbound.net
|
||||
verisign.com
|
||||
vk.com
|
||||
vk.me
|
||||
vk.ru
|
||||
vkontakte.com
|
||||
vkontakte.ru
|
||||
vlc.org
|
||||
watsapp.net
|
||||
weather.mail.ru
|
||||
windowsupdate.com
|
||||
www.baidu.com
|
||||
www.bbc.co.uk
|
||||
www.internic.net
|
||||
www.opennet.ru
|
||||
www.topgear.com
|
||||
ya.ru
|
||||
yahoo.com
|
||||
yandex.com
|
||||
yandex.ru
|
||||
youtube.com
|
||||
ytimg.com
|
||||
EOT
|
||||
else
|
||||
echo "Warming up cache from $1 file..."
|
||||
$cat $1 | $dig -f - @$address >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
|
||||
echo "Saving cache..."
|
||||
script=`which unbound_cache.sh`
|
||||
[ -f "$script" ] && $script -s
|
||||
echo "Done."
|
||||
|
||||
exit 0
|
||||
+46
-695
@@ -21,16 +21,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -45,11 +45,8 @@
|
||||
#include "util/log.h"
|
||||
#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,57 +61,30 @@ 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);
|
||||
}
|
||||
|
||||
/** 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,
|
||||
static int
|
||||
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,
|
||||
struct acl_addr* node = regional_alloc(acl->region,
|
||||
sizeof(struct acl_addr));
|
||||
if(!node)
|
||||
return NULL;
|
||||
return 0;
|
||||
node->control = control;
|
||||
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
|
||||
if(complain_duplicates)
|
||||
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -127,14 +97,23 @@ 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, "allow_snoop") == 0)
|
||||
control = acl_allow_snoop;
|
||||
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;
|
||||
@@ -142,281 +121,12 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
struct sockaddr_storage addr;
|
||||
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;
|
||||
}
|
||||
}
|
||||
/* find or create node */
|
||||
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
||||
addrlen, net)) && !is_interface) {
|
||||
/* 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,
|
||||
addrlen, net, acl_allow, 1))) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
return acl_find_or_create(acl_interface, addr, addrlen, control);
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
node->taglen = bitmaplen;
|
||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||
if(!node->taglist) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** 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 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);
|
||||
return 0;
|
||||
}
|
||||
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||
if(!node->view) {
|
||||
log_err("no view with name: %s", str2);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&node->view->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_actions) {
|
||||
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
||||
sizeof(*node->tag_actions)*cfg->num_tags);
|
||||
if(!node->tag_actions) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_actions_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if(!local_zone_str2type(action, &t)) {
|
||||
log_err("cannot parse access control action type: %s %s %s",
|
||||
str, tag, action);
|
||||
return 0;
|
||||
}
|
||||
node->tag_actions[tagid] = (uint8_t)t;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check wire data parse */
|
||||
static int
|
||||
check_data(const char* data, const struct config_strlist* head)
|
||||
{
|
||||
char buf[65536];
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t len = sizeof(rr);
|
||||
int res;
|
||||
/* '.' is sufficient for validation, and it makes the call to
|
||||
* sldns_wirerr_get_type() simpler below. */
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", data);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0,
|
||||
NULL, 0);
|
||||
|
||||
/* Reject it if we would end up having CNAME and other data (including
|
||||
* another CNAME) for the same tag. */
|
||||
if(res == 0 && head) {
|
||||
const char* err_data = NULL;
|
||||
|
||||
if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) {
|
||||
/* adding CNAME while other data already exists. */
|
||||
err_data = data;
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf), "%s %s", ".", head->str);
|
||||
len = sizeof(rr);
|
||||
res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
|
||||
NULL, 0, NULL, 0);
|
||||
if(res != 0) {
|
||||
/* This should be impossible here as head->str
|
||||
* has been validated, but we check it just in
|
||||
* case. */
|
||||
return 0;
|
||||
}
|
||||
if(sldns_wirerr_get_type(rr, len, 1) ==
|
||||
LDNS_RR_TYPE_CNAME) /* already have CNAME */
|
||||
err_data = head->str;
|
||||
}
|
||||
if(err_data) {
|
||||
log_err("redirect tag data '%s' must not coexist with "
|
||||
"other data.", err_data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(res == 0)
|
||||
return 1;
|
||||
log_err("rr data [char %d] parse error %s",
|
||||
(int)LDNS_WIREPARSE_OFFSET(res)-2,
|
||||
sldns_get_errorstr_parse(res));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** 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)
|
||||
{
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_datas) {
|
||||
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
||||
acl->region, sizeof(*node->tag_datas)*cfg->num_tags);
|
||||
if(!node->tag_datas) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
node->tag_datas_size = (size_t)cfg->num_tags;
|
||||
}
|
||||
/* parse tag */
|
||||
if((tagid=find_tag_id(cfg, tag)) == -1) {
|
||||
log_err("cannot parse tag (define-tag it): %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
if((size_t)tagid >= node->tag_datas_size) {
|
||||
log_err("tagid too large for array %s %s", str, tag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check data? */
|
||||
if(!check_data(data, node->tag_datas[tagid])) {
|
||||
log_err("cannot parse access-control-tag data: %s %s '%s'",
|
||||
str, tag, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dupdata = regional_strdup(acl->region, data);
|
||||
if(!dupdata) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!cfg_region_strlist_insert(acl->region,
|
||||
&(node->tag_datas[tagid]), dupdata)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** 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;
|
||||
@@ -424,124 +134,21 @@ 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)
|
||||
{
|
||||
struct config_strbytelist* np, *p = *acl_tags;
|
||||
*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)) {
|
||||
config_del_strbytelist(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 tag actions config */
|
||||
static int
|
||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg,
|
||||
struct config_str3list** acl_tag_actions)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = *acl_tag_actions;
|
||||
*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)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* 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 */
|
||||
static int
|
||||
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg,
|
||||
struct config_str3list** acl_tag_datas)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = *acl_tag_datas;
|
||||
*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)) {
|
||||
config_deltrplstrlist(p);
|
||||
return 0;
|
||||
}
|
||||
/* 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_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v)
|
||||
int
|
||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
regional_free_all(acl->region);
|
||||
addr_tree_init(&acl->tree);
|
||||
if(!read_acl_list(acl, cfg->acls))
|
||||
return 0;
|
||||
if(!read_acl_view(acl, &cfg->acl_view, v))
|
||||
return 0;
|
||||
if(!read_acl_tags(acl, &cfg->acl_tags))
|
||||
return 0;
|
||||
if(!read_acl_tag_actions(acl, cfg, &cfg->acl_tag_actions))
|
||||
return 0;
|
||||
if(!read_acl_tag_datas(acl, cfg, &cfg->acl_tag_datas))
|
||||
if(!read_acl_list(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))
|
||||
@@ -551,275 +158,19 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
acl_interface_compare(const void* k1, const void* k2)
|
||||
enum acl_access
|
||||
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
|
||||
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
|
||||
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
|
||||
n2->addrlen);
|
||||
/* We don't care about comparing node->net. All addresses in the
|
||||
* acl_interface tree have either 32 (ipv4) or 128 (ipv6). */
|
||||
}
|
||||
|
||||
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
|
||||
acl_get_control(struct acl_addr* acl)
|
||||
{
|
||||
if(acl) return acl->control;
|
||||
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
addr, addrlen);
|
||||
if(r) return r->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
return (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
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", action, a, (int)port, n, acladdr->node.net,
|
||||
acl_access_to_str(acl));
|
||||
} else {
|
||||
verbose(VERB_ALGO, "%s query from %s port %d", action, a,
|
||||
(int)port);
|
||||
}
|
||||
}
|
||||
|
||||
+20
-100
@@ -21,29 +21,28 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef DAEMON_ACL_LIST_H
|
||||
#define DAEMON_ACL_LIST_H
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "services/view.h"
|
||||
struct config_file;
|
||||
struct regional;
|
||||
|
||||
@@ -56,20 +55,10 @@ enum acl_access {
|
||||
acl_deny = 0,
|
||||
/** disallow access, send a polite 'REFUSED' reply */
|
||||
acl_refuse,
|
||||
/** disallow any access to zones that aren't local, drop it */
|
||||
acl_deny_non_local,
|
||||
/** disallow access to zones that aren't local, 'REFUSED' reply */
|
||||
acl_refuse_non_local,
|
||||
/** allow full access for recursion (+RD) queries */
|
||||
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
|
||||
acl_allow_snoop
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -78,11 +67,11 @@ 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.
|
||||
*/
|
||||
rbtree_type tree;
|
||||
rbtree_t tree;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -94,25 +83,10 @@ struct acl_addr {
|
||||
struct addr_tree_node node;
|
||||
/** access control on this netblock */
|
||||
enum acl_access control;
|
||||
/** tag bitlist */
|
||||
uint8_t* taglist;
|
||||
/** length of the taglist (in bytes) */
|
||||
size_t taglen;
|
||||
/** array per tagnumber of localzonetype(in one byte). NULL if none. */
|
||||
uint8_t* tag_actions;
|
||||
/** size of the tag_actions_array */
|
||||
size_t tag_actions_size;
|
||||
/** array per tagnumber, with per tag a list of rdata strings.
|
||||
* NULL if none. strings are like 'A 127.0.0.1' 'AAAA ::1' */
|
||||
struct config_strlist** tag_datas;
|
||||
/** size of the tag_datas array */
|
||||
size_t tag_datas_size;
|
||||
/* 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);
|
||||
@@ -123,66 +97,23 @@ 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.
|
||||
* @param cfg: config options.
|
||||
* @param v: views structure
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
struct views* v);
|
||||
|
||||
/** compare ACL interface "addr_tree" nodes (+port) */
|
||||
int acl_interface_compare(const void* k1, const void* k2);
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return: what to do with message from this address.
|
||||
*/
|
||||
enum acl_access acl_get_control(struct acl_addr* acl);
|
||||
|
||||
/**
|
||||
* Lookup address to see its acl structure
|
||||
* Lookup address to see its access control status.
|
||||
* @param acl: structure for address storage.
|
||||
* @param addr: address to check
|
||||
* @param addrlen: length of addr.
|
||||
* @return: acl structure from this address.
|
||||
* @return: what to do with message from this address.
|
||||
*/
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen);
|
||||
enum acl_access acl_list_lookup(struct acl_list* acl,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Get memory used by acl structure.
|
||||
@@ -191,15 +122,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);
|
||||
|
||||
#endif /* DAEMON_ACL_LIST_H */
|
||||
|
||||
+216
-156
@@ -21,16 +21,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -40,68 +40,116 @@
|
||||
* to text format.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <openssl/ssl.h>
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/cachedump.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/worker.h"
|
||||
#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"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
/** convert to ldns rr */
|
||||
static ldns_rr*
|
||||
to_rr(struct ub_packed_rrset_key* k, struct packed_rrset_data* d,
|
||||
time_t now, size_t i, uint16_t type)
|
||||
{
|
||||
ldns_rr* rr = ldns_rr_new();
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
log_assert(i < d->count + d->rrsig_count);
|
||||
if(!rr) {
|
||||
return NULL;
|
||||
}
|
||||
ldns_rr_set_type(rr, type);
|
||||
ldns_rr_set_class(rr, ntohs(k->rk.rrset_class));
|
||||
if(d->rr_ttl[i] < now)
|
||||
ldns_rr_set_ttl(rr, 0);
|
||||
else ldns_rr_set_ttl(rr, d->rr_ttl[i] - now);
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
/* we drop detailed error in status */
|
||||
ldns_rr_free(rr);
|
||||
return NULL;
|
||||
}
|
||||
ldns_rr_set_owner(rr, rdf);
|
||||
pos = 0;
|
||||
status = ldns_wire2rdf(rr, d->rr_data[i], d->rr_len[i], &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
/* we drop detailed error in status */
|
||||
ldns_rr_free(rr);
|
||||
return NULL;
|
||||
}
|
||||
return rr;
|
||||
}
|
||||
|
||||
/** dump one rrset zonefile line */
|
||||
static int
|
||||
dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
|
||||
dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now, size_t i, uint16_t type)
|
||||
{
|
||||
char s[65535];
|
||||
if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
|
||||
char* s;
|
||||
ldns_rr* rr = to_rr(k, d, now, i, type);
|
||||
if(!rr) {
|
||||
return ssl_printf(ssl, "BADRR\n");
|
||||
}
|
||||
return ssl_printf(ssl, "%s", s);
|
||||
s = ldns_rr2str(rr);
|
||||
ldns_rr_free(rr);
|
||||
if(!s) {
|
||||
return ssl_printf(ssl, "BADRR\n");
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s", s)) {
|
||||
free(s);
|
||||
return 0;
|
||||
}
|
||||
free(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** dump rrset key and data info */
|
||||
static int
|
||||
dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
|
||||
dump_rrset(SSL* 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 1;
|
||||
if(k->id == 0) return 1; /* deleted */
|
||||
if(d->ttl < now) return 1; /* expired */
|
||||
|
||||
/* meta line */
|
||||
if(!ssl_printf(ssl, ";rrset%s " ARG_LL "d %u %u %d %d\n",
|
||||
if(!ssl_printf(ssl, ";rrset%s %lld %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++) {
|
||||
if(!dump_rrset_line(ssl, k, now, i))
|
||||
for(i=0; i<d->count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, d, now, i, ntohs(k->rk.type)))
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<d->rrsig_count; i++) {
|
||||
if(!dump_rrset_line(ssl, k, d, now, i+d->count,
|
||||
LDNS_RR_TYPE_RRSIG))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** dump lruhash rrset cache */
|
||||
static int
|
||||
dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
@@ -120,7 +168,7 @@ dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
|
||||
|
||||
/** dump rrset cache */
|
||||
static int
|
||||
dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
struct rrset_cache* r = worker->env.rrset_cache;
|
||||
size_t slab;
|
||||
@@ -139,12 +187,22 @@ dump_rrset_cache(RES* ssl, struct worker* worker)
|
||||
|
||||
/** dump message to rrset reference */
|
||||
static int
|
||||
dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
{
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
char* nm, *tp, *cl;
|
||||
nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
|
||||
tp = sldns_wire2str_type(ntohs(k->rk.type));
|
||||
cl = sldns_wire2str_class(ntohs(k->rk.rrset_class));
|
||||
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->rk.dname, k->rk.dname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
return ssl_printf(ssl, "BADREF\n");
|
||||
}
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
tp = ldns_rr_type2str(ntohs(k->rk.type));
|
||||
cl = ldns_rr_class2str(ntohs(k->rk.rrset_class));
|
||||
if(!nm || !cl || !tp) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
@@ -166,16 +224,26 @@ dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
|
||||
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
|
||||
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
time_t now)
|
||||
{
|
||||
size_t i;
|
||||
char* nm, *tp, *cl;
|
||||
ldns_rdf* rdf;
|
||||
ldns_status status;
|
||||
size_t pos;
|
||||
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);
|
||||
pos = 0;
|
||||
status = ldns_wire2dname(&rdf, k->qname, k->qname_len, &pos);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
return 1; /* skip this entry */
|
||||
}
|
||||
nm = ldns_rdf2str(rdf);
|
||||
ldns_rdf_deep_free(rdf);
|
||||
tp = ldns_rr_type2str(k->qtype);
|
||||
cl = ldns_rr_class2str(k->qclass);
|
||||
if(!nm || !tp || !cl) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
@@ -191,15 +259,13 @@ dump_msg(RES* ssl, struct query_info* k, struct reply_info* d, time_t now)
|
||||
}
|
||||
|
||||
/* meta line */
|
||||
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u %d %s\n",
|
||||
if(!ssl_printf(ssl, "msg %s %s %s %d %d %lld %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->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets,
|
||||
(int)d->reason_bogus,
|
||||
d->reason_bogus_str?d->reason_bogus_str:"")) {
|
||||
(unsigned)d->ar_numrrsets)) {
|
||||
free(nm);
|
||||
free(tp);
|
||||
free(cl);
|
||||
@@ -227,15 +293,13 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
||||
struct query_info** k, struct reply_info** d)
|
||||
{
|
||||
struct reply_info* rep = (struct reply_info*)e->data;
|
||||
if(rep->rrset_count > RR_COUNT_MAX)
|
||||
return 0; /* to protect against integer overflow */
|
||||
*d = (struct reply_info*)regional_alloc_init(region, e->data,
|
||||
sizeof(struct reply_info) +
|
||||
sizeof(struct rrset_ref) * (rep->rrset_count-1) +
|
||||
sizeof(struct ub_packed_rrset_key*) * rep->rrset_count);
|
||||
if(!*d)
|
||||
return 0;
|
||||
(*d)->rrsets = (struct ub_packed_rrset_key**)(void *)(
|
||||
(*d)->rrsets = (struct ub_packed_rrset_key**)(
|
||||
(uint8_t*)(&((*d)->ref[0])) +
|
||||
sizeof(struct rrset_ref) * rep->rrset_count);
|
||||
*k = (struct query_info*)regional_alloc_init(region,
|
||||
@@ -249,7 +313,7 @@ copy_msg(struct regional* region, struct lruhash_entry* e,
|
||||
|
||||
/** dump lruhash msg cache */
|
||||
static int
|
||||
dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
struct query_info* k;
|
||||
@@ -277,7 +341,7 @@ dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
|
||||
|
||||
/** dump msg cache */
|
||||
static int
|
||||
dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
dump_msg_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
struct slabhash* sh = worker->env.msg_cache;
|
||||
size_t slab;
|
||||
@@ -294,7 +358,7 @@ dump_msg_cache(RES* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
dump_cache(RES* ssl, struct worker* worker)
|
||||
dump_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
if(!dump_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -305,74 +369,96 @@ dump_cache(RES* ssl, struct worker* worker)
|
||||
|
||||
/** read a line from ssl into buffer */
|
||||
static int
|
||||
ssl_read_buf(RES* ssl, sldns_buffer* buf)
|
||||
ssl_read_buf(SSL* ssl, ldns_buffer* buf)
|
||||
{
|
||||
return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
|
||||
sldns_buffer_capacity(buf));
|
||||
return ssl_read_line(ssl, (char*)ldns_buffer_begin(buf),
|
||||
ldns_buffer_capacity(buf));
|
||||
}
|
||||
|
||||
/** check fixed text on line */
|
||||
static int
|
||||
read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
|
||||
read_fixed(SSL* ssl, ldns_buffer* buf, const char* str)
|
||||
{
|
||||
if(!ssl_read_buf(ssl, buf)) return 0;
|
||||
return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
|
||||
return (strcmp((char*)ldns_buffer_begin(buf), str) == 0);
|
||||
}
|
||||
|
||||
/** load an RR into rrset */
|
||||
static int
|
||||
load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
|
||||
load_rr(SSL* ssl, ldns_buffer* buf, struct regional* region,
|
||||
struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
|
||||
unsigned int i, int is_rrsig, int* go_on, time_t now)
|
||||
{
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t rr_len = sizeof(rr), dname_len = 0;
|
||||
int status;
|
||||
ldns_rr* rr;
|
||||
ldns_status status;
|
||||
|
||||
/* read the line */
|
||||
if(!ssl_read_buf(ssl, buf))
|
||||
return 0;
|
||||
if(strncmp((char*)sldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
|
||||
if(strncmp((char*)ldns_buffer_begin(buf), "BADRR\n", 6) == 0) {
|
||||
*go_on = 0;
|
||||
return 1;
|
||||
}
|
||||
status = sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr,
|
||||
&rr_len, &dname_len, 3600, NULL, 0, NULL, 0);
|
||||
if(status != 0) {
|
||||
status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
|
||||
LDNS_DEFAULT_TTL, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot parse rr: %s: %s",
|
||||
sldns_get_errorstr_parse(status),
|
||||
(char*)sldns_buffer_begin(buf));
|
||||
ldns_get_errorstr_by_id(status),
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
if(is_rrsig && sldns_wirerr_get_type(rr, rr_len, dname_len)
|
||||
!= LDNS_RR_TYPE_RRSIG) {
|
||||
if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
|
||||
log_warn("error expected rrsig but got %s",
|
||||
(char*)sldns_buffer_begin(buf));
|
||||
(char*)ldns_buffer_begin(buf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* convert ldns rr into packed_rr */
|
||||
d->rr_ttl[i] = (time_t)sldns_wirerr_get_ttl(rr, rr_len, dname_len) + now;
|
||||
sldns_buffer_clear(buf);
|
||||
d->rr_len[i] = sldns_wirerr_get_rdatalen(rr, rr_len, dname_len)+2;
|
||||
d->rr_ttl[i] = ldns_rr_ttl(rr) + now;
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_skip(buf, 2);
|
||||
status = ldns_rr_rdata2buffer_wire(buf, rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot rr2wire: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
ldns_buffer_write_u16_at(buf, 0, ldns_buffer_limit(buf) - 2);
|
||||
|
||||
d->rr_len[i] = ldns_buffer_limit(buf);
|
||||
d->rr_data[i] = (uint8_t*)regional_alloc_init(region,
|
||||
sldns_wirerr_get_rdatawl(rr, rr_len, dname_len), d->rr_len[i]);
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!d->rr_data[i]) {
|
||||
ldns_rr_free(rr);
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if first entry, fill the key structure */
|
||||
if(i==0) {
|
||||
rk->rk.type = htons(sldns_wirerr_get_type(rr, rr_len, dname_len));
|
||||
rk->rk.rrset_class = htons(sldns_wirerr_get_class(rr, rr_len, dname_len));
|
||||
rk->rk.dname_len = dname_len;
|
||||
rk->rk.dname = regional_alloc_init(region, rr, dname_len);
|
||||
rk->rk.type = htons(ldns_rr_get_type(rr));
|
||||
rk->rk.rrset_class = htons(ldns_rr_get_class(rr));
|
||||
ldns_buffer_clear(buf);
|
||||
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot dname2buffer: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
rk->rk.dname_len = ldns_buffer_limit(buf);
|
||||
rk->rk.dname = regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!rk->rk.dname) {
|
||||
log_warn("error out of memory");
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ldns_rr_free(rr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -388,7 +474,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;
|
||||
@@ -399,7 +485,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*) +
|
||||
@@ -409,7 +495,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;
|
||||
@@ -432,16 +518,15 @@ 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;
|
||||
}
|
||||
|
||||
/** load an rrset entry */
|
||||
static int
|
||||
load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_rrset(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
char* s = (char*)ldns_buffer_begin(buf);
|
||||
struct regional* region = worker->scratchpad;
|
||||
struct ub_packed_rrset_key* rk;
|
||||
struct packed_rrset_data* d;
|
||||
@@ -468,7 +553,7 @@ load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
s += 10;
|
||||
rk->rk.flags |= PACKED_RRSET_NSEC_AT_APEX;
|
||||
}
|
||||
if(sscanf(s, " " ARG_LL "d %u %u %u %u", &ttl, &rr_count, &rrsig_count,
|
||||
if(sscanf(s, " %lld %u %u %u %u", &ttl, &rr_count, &rrsig_count,
|
||||
&trust, &security) != 5) {
|
||||
log_warn("error bad rrset spec %s", s);
|
||||
return 0;
|
||||
@@ -477,10 +562,6 @@ load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
log_warn("bad rrset without contents");
|
||||
return 0;
|
||||
}
|
||||
if(rr_count > RR_COUNT_MAX || rrsig_count > RR_COUNT_MAX) {
|
||||
log_warn("bad rrset with too many rrs");
|
||||
return 0;
|
||||
}
|
||||
d->count = (size_t)rr_count;
|
||||
d->rrsig_count = (size_t)rrsig_count;
|
||||
d->security = (enum sec_status)security;
|
||||
@@ -523,12 +604,12 @@ load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load rrset cache */
|
||||
static int
|
||||
load_rrset_cache(RES* ssl, struct worker* worker)
|
||||
load_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
ldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
|
||||
while(ssl_read_buf(ssl, buf) &&
|
||||
strcmp((char*)sldns_buffer_begin(buf), "END_RRSET_CACHE")!=0) {
|
||||
strcmp((char*)ldns_buffer_begin(buf), "END_RRSET_CACHE")!=0) {
|
||||
if(!load_rrset(ssl, buf, worker))
|
||||
return 0;
|
||||
}
|
||||
@@ -537,13 +618,13 @@ load_rrset_cache(RES* ssl, struct worker* worker)
|
||||
|
||||
/** read qinfo from next three words */
|
||||
static char*
|
||||
load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
load_qinfo(char* str, struct query_info* qinfo, ldns_buffer* buf,
|
||||
struct regional* region)
|
||||
{
|
||||
/* s is part of the buf */
|
||||
char* s = str;
|
||||
uint8_t rr[LDNS_RR_BUF_SIZE];
|
||||
size_t rr_len = sizeof(rr), dname_len = 0;
|
||||
int status;
|
||||
ldns_rr* rr;
|
||||
ldns_status status;
|
||||
|
||||
/* skip three words */
|
||||
s = strchr(str, ' ');
|
||||
@@ -557,18 +638,26 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
s++;
|
||||
|
||||
/* parse them */
|
||||
status = sldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len,
|
||||
NULL, 0, NULL, 0);
|
||||
if(status != 0) {
|
||||
status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot parse: %s %s",
|
||||
sldns_get_errorstr_parse(status), str);
|
||||
ldns_get_errorstr_by_id(status), str);
|
||||
return NULL;
|
||||
}
|
||||
qinfo->qtype = sldns_wirerr_get_type(rr, rr_len, dname_len);
|
||||
qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
|
||||
qinfo->qname_len = dname_len;
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
|
||||
qinfo->local_alias = NULL;
|
||||
qinfo->qtype = ldns_rr_get_type(rr);
|
||||
qinfo->qclass = ldns_rr_get_class(rr);
|
||||
ldns_buffer_clear(buf);
|
||||
status = ldns_dname2buffer_wire(buf, ldns_rr_owner(rr));
|
||||
ldns_rr_free(rr);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
log_warn("error cannot dname2wire: %s",
|
||||
ldns_get_errorstr_by_id(status));
|
||||
return NULL;
|
||||
}
|
||||
ldns_buffer_flip(buf);
|
||||
qinfo->qname_len = ldns_buffer_limit(buf);
|
||||
qinfo->qname = (uint8_t*)regional_alloc_init(region,
|
||||
ldns_buffer_begin(buf), ldns_buffer_limit(buf));
|
||||
if(!qinfo->qname) {
|
||||
log_warn("error out of memory");
|
||||
return NULL;
|
||||
@@ -579,11 +668,11 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
|
||||
/** load a msg rrset reference */
|
||||
static int
|
||||
load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
load_ref(SSL* ssl, ldns_buffer* buf, struct worker* worker,
|
||||
struct regional *region, struct ub_packed_rrset_key** rrset,
|
||||
int* go_on)
|
||||
{
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
char* s = (char*)ldns_buffer_begin(buf);
|
||||
struct query_info qinfo;
|
||||
unsigned int flags;
|
||||
struct ub_packed_rrset_key* k;
|
||||
@@ -596,7 +685,7 @@ load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = load_qinfo(s, &qinfo, region);
|
||||
s = load_qinfo(s, &qinfo, buf, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -624,19 +713,16 @@ load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
|
||||
/** load a msg entry */
|
||||
static int
|
||||
load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
load_msg(SSL* ssl, ldns_buffer* buf, struct worker* worker)
|
||||
{
|
||||
struct regional* region = worker->scratchpad;
|
||||
struct query_info qinf;
|
||||
struct reply_info rep;
|
||||
char* s = (char*)sldns_buffer_begin(buf);
|
||||
char* s = (char*)ldns_buffer_begin(buf);
|
||||
unsigned int flags, qdcount, security, an, ns, ar;
|
||||
long long ttl;
|
||||
size_t i;
|
||||
int go_on = 1;
|
||||
int ede;
|
||||
int consumed = 0;
|
||||
char* ede_str = NULL;
|
||||
|
||||
regional_free_all(region);
|
||||
|
||||
@@ -645,38 +731,26 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
return 0;
|
||||
}
|
||||
s += 4;
|
||||
s = load_qinfo(s, &qinf, region);
|
||||
s = load_qinfo(s, &qinf, buf, region);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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 %lld %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;
|
||||
rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
|
||||
rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
|
||||
rep.security = (enum sec_status)security;
|
||||
if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
|
||||
log_warn("error too many rrsets");
|
||||
return 0; /* protect against integer overflow in alloc */
|
||||
}
|
||||
rep.an_numrrsets = (size_t)an;
|
||||
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);
|
||||
|
||||
@@ -691,8 +765,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)) {
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) {
|
||||
log_warn("error out of memory");
|
||||
return 0;
|
||||
}
|
||||
@@ -701,12 +774,12 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
|
||||
/** load msg cache */
|
||||
static int
|
||||
load_msg_cache(RES* ssl, struct worker* worker)
|
||||
load_msg_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
sldns_buffer* buf = worker->env.scratch_buffer;
|
||||
ldns_buffer* buf = worker->env.scratch_buffer;
|
||||
if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
|
||||
while(ssl_read_buf(ssl, buf) &&
|
||||
strcmp((char*)sldns_buffer_begin(buf), "END_MSG_CACHE")!=0) {
|
||||
strcmp((char*)ldns_buffer_begin(buf), "END_MSG_CACHE")!=0) {
|
||||
if(!load_msg(ssl, buf, worker))
|
||||
return 0;
|
||||
}
|
||||
@@ -714,7 +787,7 @@ load_msg_cache(RES* ssl, struct worker* worker)
|
||||
}
|
||||
|
||||
int
|
||||
load_cache(RES* ssl, struct worker* worker)
|
||||
load_cache(SSL* ssl, struct worker* worker)
|
||||
{
|
||||
if(!load_rrset_cache(ssl, worker))
|
||||
return 0;
|
||||
@@ -725,7 +798,7 @@ load_cache(RES* ssl, struct worker* worker)
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
@@ -770,8 +843,8 @@ print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
return;
|
||||
continue; /* skip stuff not in infra cache */
|
||||
}
|
||||
if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl " ARG_LL "d, "
|
||||
"ping %d var %d rtt %d, tA %d, tAAAA %d, tother %d",
|
||||
if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl %lld, ping %d "
|
||||
"var %d rtt %d, tA %d, tAAAA %d, tother %d",
|
||||
lame?"LAME ":"", dlame?"NoDNSSEC ":"",
|
||||
a->lame?"AddrWasParentSide ":"",
|
||||
rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
|
||||
@@ -801,7 +874,7 @@ print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
{
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
|
||||
@@ -829,7 +902,7 @@ print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
/* deep links into the iterator module */
|
||||
@@ -839,44 +912,36 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
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;
|
||||
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||
qinfo.qclass = LDNS_RR_CLASS_IN;
|
||||
qinfo.local_alias = NULL;
|
||||
|
||||
dname_str(nm, b);
|
||||
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 "
|
||||
@@ -896,26 +961,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);
|
||||
|
||||
+13
-14
@@ -21,16 +21,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,6 @@
|
||||
#ifndef DAEMON_DUMPCACHE_H
|
||||
#define DAEMON_DUMPCACHE_H
|
||||
struct worker;
|
||||
#include "daemon/remote.h"
|
||||
|
||||
/**
|
||||
* Dump cache(s) to text
|
||||
@@ -81,7 +80,7 @@ struct worker;
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl print error.
|
||||
*/
|
||||
int dump_cache(RES* ssl, struct worker* worker);
|
||||
int dump_cache(SSL* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Load cache(s) from text
|
||||
@@ -90,7 +89,7 @@ int dump_cache(RES* ssl, struct worker* worker);
|
||||
* ptrs to the caches.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int load_cache(RES* ssl, struct worker* worker);
|
||||
int load_cache(SSL* ssl, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Print the delegation used to lookup for this name.
|
||||
@@ -102,7 +101,7 @@ int load_cache(RES* ssl, struct worker* worker);
|
||||
* @param nmlabs: labels in name.
|
||||
* @return false on ssl error.
|
||||
*/
|
||||
int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int nmlabs);
|
||||
|
||||
#endif /* DAEMON_DUMPCACHE_H */
|
||||
|
||||
+51
-482
@@ -21,16 +21,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -56,16 +56,12 @@
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef HAVE_NSS
|
||||
/* nss3 */
|
||||
#include "nss.h"
|
||||
#endif
|
||||
|
||||
#include <ldns/ldns.h>
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/remote.h"
|
||||
@@ -73,38 +69,19 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/edns.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/view.h"
|
||||
#include "services/modstack.h"
|
||||
#include "services/authzone.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/net_help.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
|
||||
/** How many quit requests happened. */
|
||||
static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
@@ -114,8 +91,10 @@ static int sig_record_reload = 0;
|
||||
/** cleaner ssl memory freeup */
|
||||
static void* comp_meth = NULL;
|
||||
#endif
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/** remove buffers for parsing and init */
|
||||
int ub_c_lex_destroy(void);
|
||||
#endif
|
||||
|
||||
/** used when no other sighandling happens, so we don't die
|
||||
* when multiple signals in quick succession are sent to us.
|
||||
@@ -125,9 +104,8 @@ int ub_c_lex_destroy(void);
|
||||
static RETSIGTYPE record_sigh(int sig)
|
||||
{
|
||||
#ifdef LIBEVENT_SIGNAL_PROBLEM
|
||||
/* cannot log, verbose here because locks may be held */
|
||||
/* quit on signal, no cleanup and statistics,
|
||||
because installed libevent version is not threadsafe */
|
||||
verbose(VERB_OPS, "quit on signal, no cleanup and statistics, "
|
||||
"because installed libevent version is not threadsafe");
|
||||
exit(0);
|
||||
#endif
|
||||
switch(sig)
|
||||
@@ -152,8 +130,7 @@ static RETSIGTYPE record_sigh(int sig)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* ignoring signal */
|
||||
break;
|
||||
log_err("ignoring signal %d", sig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,34 +195,22 @@ daemon_init(void)
|
||||
}
|
||||
#endif /* USE_WINSOCK */
|
||||
signal_handling_record();
|
||||
checklock_start();
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
|
||||
ERR_load_crypto_strings();
|
||||
# endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
ERR_load_SSL_strings();
|
||||
#endif
|
||||
# ifdef HAVE_OPENSSL_CONFIG
|
||||
OPENSSL_config("unbound");
|
||||
# endif
|
||||
# ifdef USE_GOST
|
||||
(void)sldns_key_EVP_load_gost_id();
|
||||
(void)ldns_key_EVP_load_gost_id();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
# ifndef S_SPLINT_S
|
||||
OpenSSL_add_all_algorithms();
|
||||
# endif
|
||||
# else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/* grab the COMP method ptr because openssl leaks it */
|
||||
comp_meth = (void*)SSL_COMP_get_compression_methods();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
# else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
if(!ub_openssl_lock_init())
|
||||
fatal_exit("could not init openssl locks");
|
||||
@@ -258,6 +223,8 @@ daemon_init(void)
|
||||
/* init timezone info while we are not chrooted yet */
|
||||
tzset();
|
||||
#endif
|
||||
/* open /dev/random if needed */
|
||||
ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67);
|
||||
daemon->need_to_exit = 0;
|
||||
modstack_init(&daemon->mods);
|
||||
if(!(daemon->env = (struct module_env*)calloc(1,
|
||||
@@ -265,168 +232,27 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->env->modstack = &daemon->mods;
|
||||
/* init edns_known_options */
|
||||
if(!edns_known_options_init(daemon->env)) {
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
alloc_init(&daemon->superalloc, NULL, 0);
|
||||
daemon->acl = acl_list_create();
|
||||
if(!daemon->acl) {
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->acl_interface = acl_list_create();
|
||||
if(!daemon->acl_interface) {
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->tcl = tcl_list_create();
|
||||
if(!daemon->tcl) {
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
listen_setup_locks();
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
daemon->time_last_stat = daemon->time_boot;
|
||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
if(!(daemon->env->edns_strings = edns_strings_create())) {
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
return daemon;
|
||||
}
|
||||
|
||||
static int setup_acl_for_ports(struct acl_list* list,
|
||||
struct listen_port* port_list)
|
||||
{
|
||||
struct acl_addr* acl_node;
|
||||
for(; port_list; port_list=port_list->next) {
|
||||
if(!port_list->socket) {
|
||||
/* This is mainly for testbound where port_list is
|
||||
* empty. */
|
||||
continue;
|
||||
}
|
||||
if(!(acl_node = acl_interface_insert(list,
|
||||
(struct sockaddr_storage*)port_list->socket->addr,
|
||||
port_list->socket->addrlen,
|
||||
acl_refuse))) {
|
||||
return 0;
|
||||
}
|
||||
port_list->socket->acl = acl_node;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
if(daemon->cfg->port != daemon->listening_port) {
|
||||
char** resif = NULL;
|
||||
int num_resif = 0;
|
||||
size_t i;
|
||||
struct listen_port* p0;
|
||||
daemon->reuseport = 0;
|
||||
/* free and close old ports */
|
||||
if(daemon->ports != NULL) {
|
||||
for(i=0; i<daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
}
|
||||
/* clean acl_interface */
|
||||
acl_interface_init(daemon->acl_interface);
|
||||
if(!resolve_interface_names(daemon->cfg->ifs,
|
||||
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
|
||||
listening_ports_free(daemon->ports);
|
||||
if(!(daemon->ports=listening_ports_open(daemon->cfg)))
|
||||
return 0;
|
||||
/* see if we want to reuseport */
|
||||
#ifdef SO_REUSEPORT
|
||||
if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
|
||||
daemon->reuseport = 1;
|
||||
#endif
|
||||
/* try to use reuseport */
|
||||
p0 = listening_ports_open(daemon->cfg, resif, num_resif,
|
||||
&daemon->reuseport);
|
||||
if(!p0) {
|
||||
listening_ports_free(p0);
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
if(daemon->reuseport) {
|
||||
/* reuseport was successful, allocate for it */
|
||||
daemon->num_ports = (size_t)daemon->cfg->num_threads;
|
||||
} else {
|
||||
/* do the normal, singleportslist thing,
|
||||
* reuseport not enabled or did not work */
|
||||
daemon->num_ports = 1;
|
||||
}
|
||||
if(!(daemon->ports = (struct listen_port**)calloc(
|
||||
daemon->num_ports, sizeof(*daemon->ports)))) {
|
||||
listening_ports_free(p0);
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
daemon->ports[0] = p0;
|
||||
if(!setup_acl_for_ports(daemon->acl_interface,
|
||||
daemon->ports[0])) {
|
||||
listening_ports_free(p0);
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
if(daemon->reuseport) {
|
||||
/* continue to use reuseport */
|
||||
for(i=1; i<daemon->num_ports; i++) {
|
||||
if(!(daemon->ports[i]=
|
||||
listening_ports_open(daemon->cfg,
|
||||
resif, num_resif,
|
||||
&daemon->reuseport))
|
||||
|| !daemon->reuseport ) {
|
||||
for(i=0; i<daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
if(!setup_acl_for_ports(daemon->acl_interface,
|
||||
daemon->ports[i])) {
|
||||
for(i=0; i<daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
config_del_strarray(resif, num_resif);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
config_del_strarray(resif, num_resif);
|
||||
daemon->listening_port = daemon->cfg->port;
|
||||
}
|
||||
if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
|
||||
@@ -444,19 +270,6 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_privileged(struct daemon* daemon)
|
||||
{
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to startup modules");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup modules. setup module stack.
|
||||
* @param daemon: the daemon
|
||||
@@ -466,16 +279,11 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
if(daemon->mods_inited) {
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
}
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
|
||||
if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to init modules");
|
||||
fatal_exit("failed to setup modules");
|
||||
}
|
||||
daemon->mods_inited = 1;
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -509,30 +317,6 @@ static int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
return avail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear and delete per-worker alloc caches, and free memory maintained in
|
||||
* superalloc.
|
||||
* The rrset and message caches must be empty at the time of call.
|
||||
* @param daemon: the daemon that maintains the alloc caches to be cleared.
|
||||
*/
|
||||
static void
|
||||
daemon_clear_allocs(struct daemon* daemon)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* daemon->num may be different during reloads (after configuration
|
||||
* read). Use old_num which has the correct value used to setup the
|
||||
* worker_allocs */
|
||||
for(i=0; i<daemon->old_num; i++) {
|
||||
alloc_clear(daemon->worker_allocs[i]);
|
||||
free(daemon->worker_allocs[i]);
|
||||
}
|
||||
free(daemon->worker_allocs);
|
||||
daemon->worker_allocs = NULL;
|
||||
|
||||
alloc_clear_special(&daemon->superalloc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate empty worker structures. With backptr and thread-number,
|
||||
* from 0..numthread initialised. Used as user arguments to new threads.
|
||||
@@ -547,11 +331,13 @@ daemon_create_workers(struct daemon* daemon)
|
||||
int* shufport;
|
||||
log_assert(daemon && daemon->cfg);
|
||||
if(!daemon->rand) {
|
||||
daemon->rand = ub_initstate(NULL);
|
||||
unsigned int seed = (unsigned int)time(NULL) ^
|
||||
(unsigned int)getpid() ^ 0x438;
|
||||
daemon->rand = ub_initstate(seed, NULL);
|
||||
if(!daemon->rand)
|
||||
fatal_exit("could not init random generator");
|
||||
hash_set_raninit((uint32_t)ub_random(daemon->rand));
|
||||
}
|
||||
hash_set_raninit((uint32_t)ub_random(daemon->rand));
|
||||
shufport = (int*)calloc(65536, sizeof(int));
|
||||
if(!shufport)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
@@ -559,25 +345,8 @@ daemon_create_workers(struct daemon* daemon)
|
||||
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
|
||||
|
||||
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
|
||||
if(daemon->reuseport && (int)daemon->num < (int)daemon->num_ports) {
|
||||
log_warn("cannot reduce num-threads to %d because so-reuseport "
|
||||
"so continuing with %d threads.", (int)daemon->num,
|
||||
(int)daemon->num_ports);
|
||||
daemon->num = (int)daemon->num_ports;
|
||||
}
|
||||
daemon->workers = (struct worker**)calloc((size_t)daemon->num,
|
||||
sizeof(struct worker*));
|
||||
if(!daemon->workers)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
if(daemon->cfg->dnstap) {
|
||||
#ifdef USE_DNSTAP
|
||||
daemon->dtenv = dt_create(daemon->cfg);
|
||||
if (!daemon->dtenv)
|
||||
fatal_exit("dt_create failed");
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
@@ -585,21 +354,6 @@ daemon_create_workers(struct daemon* daemon)
|
||||
/* the above is not ports/numthr, due to rounding */
|
||||
fatal_exit("could not create worker");
|
||||
}
|
||||
/* create per-worker alloc caches if not reusing existing ones. */
|
||||
if(!daemon->worker_allocs) {
|
||||
daemon->worker_allocs = (struct alloc_cache**)calloc(
|
||||
(size_t)daemon->num, sizeof(struct alloc_cache*));
|
||||
if(!daemon->worker_allocs)
|
||||
fatal_exit("could not allocate worker allocs");
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
struct alloc_cache* alloc = calloc(1,
|
||||
sizeof(struct alloc_cache));
|
||||
if (!alloc)
|
||||
fatal_exit("could not allocate worker alloc");
|
||||
alloc_init(alloc, &daemon->superalloc, i);
|
||||
daemon->worker_allocs[i] = alloc;
|
||||
}
|
||||
}
|
||||
free(shufport);
|
||||
}
|
||||
|
||||
@@ -635,7 +389,6 @@ static void*
|
||||
thread_start(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int port_num = 0;
|
||||
log_thread_set(&worker->thread_num);
|
||||
ub_thread_blocksigs();
|
||||
#ifdef THREADS_DISABLED
|
||||
@@ -643,14 +396,7 @@ thread_start(void* arg)
|
||||
tube_close_write(worker->cmd);
|
||||
close_other_pipes(worker->daemon, worker->thread_num);
|
||||
#endif
|
||||
#ifdef SO_REUSEPORT
|
||||
if(worker->daemon->cfg->so_reuseport)
|
||||
port_num = worker->thread_num % worker->daemon->num_ports;
|
||||
else
|
||||
port_num = 0;
|
||||
#endif
|
||||
if(!worker_init(worker, worker->daemon->cfg,
|
||||
worker->daemon->ports[port_num], 0))
|
||||
if(!worker_init(worker, worker->daemon->cfg, worker->daemon->ports, 0))
|
||||
fatal_exit("Could not initialize thread");
|
||||
|
||||
worker_work(worker);
|
||||
@@ -705,88 +451,17 @@ daemon_stop_others(struct daemon* daemon)
|
||||
void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
#ifdef HAVE_SYSTEMD
|
||||
int ret;
|
||||
#endif
|
||||
|
||||
log_assert(daemon);
|
||||
if(!(daemon->views = views_create()))
|
||||
fatal_exit("Could not create views: out of memory");
|
||||
/* create individual views and their localzone/data trees */
|
||||
if(!views_apply_cfg(daemon->views, daemon->cfg))
|
||||
fatal_exit("Could not set up views");
|
||||
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
|
||||
fatal_exit("Could not setup access control list");
|
||||
if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
|
||||
daemon->views))
|
||||
fatal_exit("Could not setup interface control list");
|
||||
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
||||
fatal_exit("Could not setup TCP connection limits");
|
||||
if(daemon->cfg->dnscrypt) {
|
||||
#ifdef USE_DNSCRYPT
|
||||
daemon->dnscenv = dnsc_create();
|
||||
if (!daemon->dnscenv)
|
||||
fatal_exit("dnsc_create failed");
|
||||
dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnscrypt enabled in config but unbound was not built with "
|
||||
"dnscrypt support");
|
||||
#endif
|
||||
}
|
||||
/* create global local_zones */
|
||||
if(!(daemon->local_zones = local_zones_create()))
|
||||
fatal_exit("Could not create local zones: out of memory");
|
||||
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
|
||||
fatal_exit("Could not set up local zones");
|
||||
if(!(daemon->env->fwds = forwards_create()) ||
|
||||
!forwards_apply_cfg(daemon->env->fwds, daemon->cfg))
|
||||
fatal_exit("Could not set forward zones");
|
||||
if(!(daemon->env->hints = hints_create()) ||
|
||||
!hints_apply_cfg(daemon->env->hints, daemon->cfg))
|
||||
fatal_exit("Could not set root or stub hints");
|
||||
|
||||
/* process raw response-ip configuration data */
|
||||
if(!(daemon->respip_set = respip_set_create()))
|
||||
fatal_exit("Could not create response IP set");
|
||||
if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
|
||||
fatal_exit("Could not set up response IP set");
|
||||
if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
|
||||
&have_view_respip_cfg))
|
||||
fatal_exit("Could not set up per-view response IP sets");
|
||||
daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
|
||||
have_view_respip_cfg;
|
||||
|
||||
/* setup modules */
|
||||
daemon_setup_modules(daemon);
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* Set-up EDNS strings */
|
||||
if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
|
||||
fatal_exit("Could not set up EDNS strings");
|
||||
|
||||
#ifdef USE_CACHEDB
|
||||
daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
|
||||
daemon->env);
|
||||
#endif
|
||||
/* response-ip-xxx options don't work as expected without the respip
|
||||
* module. To avoid run-time operational surprise we reject such
|
||||
* configuration. */
|
||||
if(daemon->use_response_ip &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("response-ip options require respip module");
|
||||
/* RPZ response ip triggers don't work as expected without the respip
|
||||
* module. To avoid run-time operational surprise we reject such
|
||||
* configuration. */
|
||||
if(daemon->use_rpz &&
|
||||
modstack_find(&daemon->mods, "respip") < 0)
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
*/
|
||||
@@ -794,7 +469,7 @@ daemon_fork(struct daemon* daemon)
|
||||
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
/* in libev the first inited base gets signals */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
#endif
|
||||
|
||||
@@ -808,40 +483,19 @@ daemon_fork(struct daemon* daemon)
|
||||
*/
|
||||
#if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
/* libevent has the last inited base get signals (or any base) */
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports[0], 1))
|
||||
if(!worker_init(daemon->workers[0], daemon->cfg, daemon->ports, 1))
|
||||
fatal_exit("Could not initialize main thread");
|
||||
#endif
|
||||
signal_handling_playback(daemon->workers[0]);
|
||||
|
||||
if (!shm_main_init(daemon))
|
||||
log_warn("SHM has failed");
|
||||
|
||||
/* Start resolver service on main thread. */
|
||||
#ifdef HAVE_SYSTEMD
|
||||
ret = sd_notify(0, "READY=1");
|
||||
if(ret <= 0 && getenv("NOTIFY_SOCKET"))
|
||||
fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
|
||||
"access/permission to use the socket presented by systemd.",
|
||||
getenv("NOTIFY_SOCKET"),
|
||||
(ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
if (daemon->workers[0]->need_to_exit)
|
||||
sd_notify(0, "STOPPING=1");
|
||||
else
|
||||
sd_notify(0, "RELOADING=1");
|
||||
#endif
|
||||
log_info("service stopped (%s).", PACKAGE_STRING);
|
||||
|
||||
/* we exited! a signal happened! Stop other threads */
|
||||
daemon_stop_others(daemon);
|
||||
|
||||
/* Shutdown SHM */
|
||||
shm_main_shutdown(daemon);
|
||||
|
||||
daemon->reuse_cache = daemon->workers[0]->reuse_cache;
|
||||
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
|
||||
}
|
||||
|
||||
@@ -856,125 +510,73 @@ daemon_cleanup(struct daemon* daemon)
|
||||
log_thread_set(NULL);
|
||||
/* clean up caches because
|
||||
* a) RRset IDs will be recycled after a reload, causing collisions
|
||||
* b) validation config can change, thus rrset, msg, keycache clear
|
||||
*
|
||||
* If we are trying to keep the cache as long as possible, we should
|
||||
* defer the cleanup until we know whether the new configuration allows
|
||||
* the reuse. (If we're exiting, cleanup should be done here). */
|
||||
if(!daemon->reuse_cache || daemon->need_to_exit) {
|
||||
slabhash_clear(&daemon->env->rrset_cache->table);
|
||||
slabhash_clear(daemon->env->msg_cache);
|
||||
}
|
||||
daemon->old_num = daemon->num; /* save the current num */
|
||||
forwards_delete(daemon->env->fwds);
|
||||
daemon->env->fwds = NULL;
|
||||
hints_delete(daemon->env->hints);
|
||||
daemon->env->hints = NULL;
|
||||
* b) validation config can change, thus rrset, msg, keycache clear
|
||||
* The infra cache is kept, the timing and edns info is still valid */
|
||||
slabhash_clear(&daemon->env->rrset_cache->table);
|
||||
slabhash_clear(daemon->env->msg_cache);
|
||||
local_zones_delete(daemon->local_zones);
|
||||
daemon->local_zones = NULL;
|
||||
respip_set_delete(daemon->respip_set);
|
||||
daemon->respip_set = NULL;
|
||||
views_delete(daemon->views);
|
||||
daemon->views = NULL;
|
||||
if(daemon->env->auth_zones)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module deinit during next daemon_fork() */
|
||||
/* key cache is cleared by module desetup during next daemon_init() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
/* Unless we're trying to keep the cache, worker alloc_caches should be
|
||||
* cleared and freed here. We do this after deleting workers to
|
||||
* guarantee that the alloc caches are valid throughout the lifetime
|
||||
* of workers. */
|
||||
if(!daemon->reuse_cache || daemon->need_to_exit)
|
||||
daemon_clear_allocs(daemon);
|
||||
daemon->num = 0;
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
#endif
|
||||
#ifdef USE_DNSCRYPT
|
||||
dnsc_delete(daemon->dnscenv);
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
daemon_delete(struct daemon* daemon)
|
||||
{
|
||||
size_t i;
|
||||
if(!daemon)
|
||||
return;
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
modstack_call_destartup(&daemon->mods, daemon->env);
|
||||
modstack_free(&daemon->mods);
|
||||
modstack_desetup(&daemon->mods, daemon->env);
|
||||
daemon_remote_delete(daemon->rc);
|
||||
for(i = 0; i < daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
listening_ports_free(daemon->ports);
|
||||
listening_ports_free(daemon->rc_ports);
|
||||
if(daemon->env) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
rrset_cache_delete(daemon->env->rrset_cache);
|
||||
infra_delete(daemon->env->infra_cache);
|
||||
edns_known_options_delete(daemon->env);
|
||||
edns_strings_delete(daemon->env->edns_strings);
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
listen_desetup_locks();
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
#ifdef HAVE_SSL
|
||||
listen_sslctx_delete_ticket_keys();
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
|
||||
#endif
|
||||
free(daemon);
|
||||
#ifdef LEX_HAS_YYLEX_DESTROY
|
||||
/* lex cleanup */
|
||||
ub_c_lex_destroy();
|
||||
#endif
|
||||
/* libcrypto cleanup */
|
||||
#ifdef HAVE_SSL
|
||||
# if defined(USE_GOST)
|
||||
sldns_key_EVP_unload_gost();
|
||||
# if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
ldns_key_EVP_unload_gost();
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS && HAVE_DECL_SK_SSL_COMP_POP_FREE
|
||||
# ifndef S_SPLINT_S
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
sk_SSL_COMP_pop_free(comp_meth, (void(*)())CRYPTO_free);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
# ifdef HAVE_OPENSSL_CONFIG
|
||||
EVP_cleanup();
|
||||
# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE) && defined(HAVE_ENGINE_CLEANUP)
|
||||
ENGINE_cleanup();
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
# endif
|
||||
# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
CRYPTO_cleanup_all_ex_data(); /* safe, no more threads right now */
|
||||
# endif
|
||||
# ifdef HAVE_ERR_FREE_STRINGS
|
||||
ERR_remove_state(0);
|
||||
ERR_free_strings();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
RAND_cleanup();
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
ub_openssl_lock_delete();
|
||||
# endif
|
||||
#ifndef HAVE_ARC4RANDOM
|
||||
_ARC4_LOCK_DESTROY();
|
||||
#endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_Shutdown();
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
@@ -989,44 +591,11 @@ daemon_delete(struct daemon* daemon)
|
||||
|
||||
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
int new_num = cfg->num_threads?cfg->num_threads:1;
|
||||
|
||||
daemon->cfg = cfg;
|
||||
config_apply(cfg);
|
||||
|
||||
/* If this is a reload and we deferred the decision on whether to
|
||||
* reuse the alloc, RRset, and message caches, then check to see if
|
||||
* it's safe to keep the caches:
|
||||
* - changing the number of threads is obviously incompatible with
|
||||
* keeping the per-thread alloc caches. It also means we have to
|
||||
* clear RRset and message caches. (note that 'new_num' may be
|
||||
* adjusted in daemon_create_workers, but for our purpose we can
|
||||
* simply compare it with 'old_num'; if they are equal here,
|
||||
* 'new_num' won't be adjusted to a different value than 'old_num').
|
||||
* - changing RRset cache size effectively clears any remaining cache
|
||||
* entries. We could keep their keys in alloc caches, but it would
|
||||
* be more consistent with the sense of the change to clear allocs
|
||||
* and free memory. To do so we also have to clear message cache.
|
||||
* - only changing message cache size does not necessarily affect
|
||||
* RRset or alloc cache. But almost all new subsequent queries will
|
||||
* require recursive resolution anyway, so it doesn't help much to
|
||||
* just keep RRset and alloc caches. For simplicity we clear/free
|
||||
* the other two, too. */
|
||||
if(daemon->worker_allocs &&
|
||||
(new_num != daemon->old_num ||
|
||||
!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs) ||
|
||||
!slabhash_is_size(&daemon->env->rrset_cache->table,
|
||||
cfg->rrset_cache_size, cfg->rrset_cache_slabs)))
|
||||
{
|
||||
log_warn("cannot reuse caches due to critical config change");
|
||||
slabhash_clear(&daemon->env->rrset_cache->table);
|
||||
slabhash_clear(daemon->env->msg_cache);
|
||||
daemon_clear_allocs(daemon);
|
||||
}
|
||||
|
||||
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
|
||||
cfg->msg_cache_slabs)) {
|
||||
if(!daemon->env->msg_cache ||
|
||||
cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
|
||||
cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
|
||||
slabhash_delete(daemon->env->msg_cache);
|
||||
daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
|
||||
HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
|
||||
|
||||
+15
-68
@@ -21,16 +21,16 @@
|
||||
* 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.
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -45,6 +45,9 @@
|
||||
#include "util/locks.h"
|
||||
#include "util/alloc.h"
|
||||
#include "services/modstack.h"
|
||||
#ifdef UB_ON_WINDOWS
|
||||
# include "util/winsock_event.h"
|
||||
#endif
|
||||
struct config_file;
|
||||
struct worker;
|
||||
struct listen_port;
|
||||
@@ -53,21 +56,8 @@ struct module_env;
|
||||
struct rrset_cache;
|
||||
struct acl_list;
|
||||
struct local_zones;
|
||||
struct views;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
struct respip_set;
|
||||
struct shm_main_info;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
struct dt_env;
|
||||
#endif
|
||||
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
#ifdef USE_DNSCRYPT
|
||||
struct dnsc_env;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Structure holding worker list.
|
||||
@@ -82,13 +72,8 @@ struct daemon {
|
||||
char* pidfile;
|
||||
/** port number that has ports opened. */
|
||||
int listening_port;
|
||||
/** array of listening ports, opened. Listening ports per worker,
|
||||
* or just one element[0] shared by the worker threads. */
|
||||
struct listen_port** ports;
|
||||
/** size of ports array */
|
||||
size_t num_ports;
|
||||
/** reuseport is enabled if true */
|
||||
int reuseport;
|
||||
/** listening ports, opened, to be shared by threads */
|
||||
struct listen_port* ports;
|
||||
/** port number for remote that has ports opened. */
|
||||
int rc_port;
|
||||
/** listening ports for remote control */
|
||||
@@ -99,12 +84,8 @@ struct daemon {
|
||||
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*/
|
||||
@@ -115,39 +96,14 @@ 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 */
|
||||
struct local_zones* local_zones;
|
||||
/** last time of statistics printout */
|
||||
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
|
||||
struct shm_main_info* shm_info;
|
||||
/** 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
|
||||
/** reuse existing cache on reload if other conditions allow it. */
|
||||
int reuse_cache;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -164,15 +120,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.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user