mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f241140a5f | ||
|
|
621495e173 | ||
|
|
2ae646d875 |
@@ -1 +0,0 @@
|
||||
testdata/*.[0-9] linguist-documentation
|
||||
-39
@@ -1,39 +0,0 @@
|
||||
*.lo
|
||||
*.o
|
||||
/.libs/
|
||||
/Makefile
|
||||
/autom4te.cache/
|
||||
/config.h
|
||||
/config.log
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/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
|
||||
/smallapp/unbound-control-setup.sh
|
||||
/unbound
|
||||
/unbound-anchor
|
||||
/unbound-checkconf
|
||||
/unbound-control
|
||||
/unbound-control-setup
|
||||
/unbound-host
|
||||
/unbound.h
|
||||
/asynclook
|
||||
/delayer
|
||||
/lock-verify
|
||||
/memstats
|
||||
/perf
|
||||
/petal
|
||||
/pktview
|
||||
/streamtcp
|
||||
/testbound
|
||||
/unittest
|
||||
|
||||
@@ -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.
|
||||
|
||||
+220
-1242
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
Unbound README
|
||||
* ./configure && make && make install
|
||||
* on BSDs and Solaris use gmake (GNU make).
|
||||
* 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.
|
||||
many (10000) outgoing ports. By default 16 ports are used and the
|
||||
builtin alternative is equally capable and a little faster.
|
||||
* More detailed README, README.svn, README.tests in doc directory
|
||||
* manual pages can be found in doc directory, and are installed, unbound(8).
|
||||
* example configuration file doc/example.conf
|
||||
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
# ===========================================================================
|
||||
# http://autoconf-archive.cryp.to/ac_pkg_swig.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AC_PROG_SWIG([major.minor.micro])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# 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.)
|
||||
#
|
||||
# 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:
|
||||
#
|
||||
# AC_PROG_SWIG(1.3.17)
|
||||
# SWIG_ENABLE_CXX
|
||||
# SWIG_MULTI_MODULE_SUPPORT
|
||||
# SWIG_PYTHON
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2008-04-12
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2008 Sebastian Huber <sebastian-huber@web.de>
|
||||
# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
|
||||
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
|
||||
# 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
|
||||
# Free Software Foundation; either version 2 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <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
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf 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.
|
||||
|
||||
AC_DEFUN([AC_PROG_SWIG],[
|
||||
AC_PATH_PROG([SWIG],[swig])
|
||||
if test -z "$SWIG" ; then
|
||||
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
|
||||
# Calculate the required version number components
|
||||
[required=$1]
|
||||
[required_major=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_major" ; then
|
||||
[required_major=0]
|
||||
fi
|
||||
[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_patch=`echo $required | sed 's/[^0-9].*//'`]
|
||||
if test -z "$required_patch" ; then
|
||||
[required_patch=0]
|
||||
fi
|
||||
# Calculate the available version number components
|
||||
[available=$swig_version]
|
||||
[available_major=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_major" ; then
|
||||
[available_major=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_minor=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_minor" ; then
|
||||
[available_minor=0]
|
||||
fi
|
||||
[available=`echo $available | sed 's/[0-9]*[^0-9]//'`]
|
||||
[available_patch=`echo $available | sed 's/[^0-9].*//'`]
|
||||
if test -z "$available_patch" ; then
|
||||
[available_patch=0]
|
||||
fi
|
||||
[badversion=0]
|
||||
if test $available_major -lt $required_major ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -lt $required_minor ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $available_major -eq $required_major \
|
||||
-a $available_minor -eq $required_minor \
|
||||
-a $available_patch -lt $required_patch ; then
|
||||
[badversion=1]
|
||||
fi
|
||||
if test $badversion -eq 1 ; then
|
||||
AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
|
||||
SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
|
||||
else
|
||||
AC_MSG_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='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([SWIG_LIB])
|
||||
])
|
||||
Vendored
+4303
-7094
File diff suppressed because it is too large
Load Diff
-1451
File diff suppressed because it is too large
Load Diff
+280
@@ -0,0 +1,280 @@
|
||||
##### http://autoconf-archive.cryp.to/acx_pthread.html
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro figures out how to build C programs using POSIX threads.
|
||||
# It sets the PTHREAD_LIBS output variable to the threads library and
|
||||
# linker flags, and the PTHREAD_CFLAGS output variable to any special
|
||||
# C compiler 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 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 link it with them as well. e.g. you should link
|
||||
# with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
|
||||
# $LIBS
|
||||
#
|
||||
# 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"
|
||||
# CC="$PTHREAD_CC"
|
||||
#
|
||||
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
|
||||
# constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
|
||||
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
|
||||
#
|
||||
# ACTION-IF-FOUND is a list of shell commands to run if a threads
|
||||
# library is found, and ACTION-IF-NOT-FOUND is a list of commands to
|
||||
# run it if it is not found. If ACTION-IF-FOUND is not specified, the
|
||||
# default action will define HAVE_PTHREAD.
|
||||
#
|
||||
# Please let the authors know if this macro fails on any platform, or
|
||||
# if you have any other suggestions or comments. This macro was based
|
||||
# on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/)
|
||||
# (with help from M. Frigo), as well as ac_pthread and hb_pthread
|
||||
# macros posted by Alejandro Forero Cuervo to the autoconf macro
|
||||
# repository. We are also grateful for the helpful feedback of
|
||||
# numerous users.
|
||||
#
|
||||
# LAST MODIFICATION
|
||||
#
|
||||
# 2006-05-29
|
||||
#
|
||||
# COPYLEFT
|
||||
#
|
||||
# Copyright (c) 2006 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
# 02111-1307, USA.
|
||||
#
|
||||
# As a special exception, the respective Autoconf Macro's copyright
|
||||
# owner gives unlimited permission to copy, distribute and modify the
|
||||
# configure scripts that are the output of Autoconf when processing
|
||||
# the Macro. You need not follow the terms of the GNU General Public
|
||||
# License when using or distributing such scripts, even though
|
||||
# portions of the text of the Macro appear in them. The GNU General
|
||||
# Public License (GPL) does govern all other use of the material that
|
||||
# constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the
|
||||
# Autoconf Macro released by the Autoconf 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.
|
||||
|
||||
AC_DEFUN([ACX_PTHREAD], [
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
acx_pthread_ok=no
|
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h
|
||||
# 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_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 in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
|
||||
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
|
||||
AC_MSG_RESULT($acx_pthread_ok)
|
||||
if test x"$acx_pthread_ok" = xno; then
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
fi
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (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 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.
|
||||
|
||||
acx_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:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# 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)
|
||||
# -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_cpu}-${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. (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:
|
||||
|
||||
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$acx_pthread_ok" = xno; then
|
||||
for flag in $acx_pthread_flags; do
|
||||
|
||||
case $flag in
|
||||
none)
|
||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
||||
;;
|
||||
|
||||
-*)
|
||||
AC_MSG_CHECKING([whether pthreads work with $flag])
|
||||
PTHREAD_CFLAGS="$flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
|
||||
if test x"$acx_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$flag])
|
||||
PTHREAD_LIBS="-l$flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
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
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# 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_TRY_LINK([#include <pthread.h>],
|
||||
[pthread_t th; pthread_join(th, 0);
|
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
||||
[acx_pthread_ok=yes])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
AC_MSG_RESULT($acx_pthread_ok)
|
||||
if test "x$acx_pthread_ok" = xyes; then
|
||||
break;
|
||||
fi
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
if test "x$acx_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_MSG_CHECKING([for joinable pthread attribute])
|
||||
attr_name=unknown
|
||||
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
|
||||
AC_TRY_LINK([#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_MSG_CHECKING([if more special flags are required for pthreads])
|
||||
flag=no
|
||||
case "${host_cpu}-${host_os}" in
|
||||
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
|
||||
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
|
||||
esac
|
||||
AC_MSG_RESULT(${flag})
|
||||
if test "x$flag" != xno; then
|
||||
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
|
||||
fi
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
# More AIX lossage: must compile with xlc_r or cc_r
|
||||
if test x"$GCC" != xyes; then
|
||||
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
|
||||
else
|
||||
PTHREAD_CC=$CC
|
||||
fi
|
||||
else
|
||||
PTHREAD_CC="$CC"
|
||||
fi
|
||||
|
||||
AC_SUBST(PTHREAD_LIBS)
|
||||
AC_SUBST(PTHREAD_CFLAGS)
|
||||
AC_SUBST(PTHREAD_CC)
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
if test x"$acx_pthread_ok" = xyes; then
|
||||
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
|
||||
:
|
||||
else
|
||||
acx_pthread_ok=no
|
||||
$2
|
||||
fi
|
||||
AC_LANG_RESTORE
|
||||
])dnl ACX_PTHREAD
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
#
|
||||
# Allow the use of a (user set) custom python version
|
||||
#
|
||||
AC_ARG_VAR([PYTHON_VERSION],[The installed Python
|
||||
version to use, for example '2.3'. This string
|
||||
will be appended to the Python interpreter
|
||||
canonical name.])
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
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
|
||||
|
||||
#
|
||||
# Check if you have distutils, else fail
|
||||
#
|
||||
AC_MSG_CHECKING([for the distutils Python package])
|
||||
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
|
||||
AC_MSG_RESULT([yes])
|
||||
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
|
||||
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
|
||||
PYTHON_CPPFLAGS=$python_path
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_CPPFLAGS])
|
||||
AC_SUBST([PYTHON_CPPFLAGS])
|
||||
|
||||
#
|
||||
# Check for Python library path
|
||||
#
|
||||
AC_MSG_CHECKING([for Python library path])
|
||||
if test -z "$PYTHON_LDFLAGS"; then
|
||||
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
|
||||
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
|
||||
fi
|
||||
AC_MSG_RESULT([$PYTHON_LDFLAGS])
|
||||
AC_SUBST([PYTHON_LDFLAGS])
|
||||
|
||||
#
|
||||
# Check for site packages
|
||||
#
|
||||
AC_MSG_CHECKING([for Python site-packages path])
|
||||
if test -z "$PYTHON_SITE_PKG"; then
|
||||
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])
|
||||
|
||||
#
|
||||
# final check to see if everything compiles alright
|
||||
#
|
||||
AC_MSG_CHECKING([consistency of all components of python development environment])
|
||||
AC_LANG_PUSH([C])
|
||||
# save current global flags
|
||||
ac_save_LIBS="$LIBS"
|
||||
ac_save_CPPFLAGS="$CPPFLAGS"
|
||||
|
||||
LIBS="$LIBS $PYTHON_LDFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
|
||||
AC_TRY_LINK([
|
||||
#include <Python.h>
|
||||
],[
|
||||
Py_Initialize();
|
||||
],[pythonexists=yes],[pythonexists=no])
|
||||
|
||||
AC_MSG_RESULT([$pythonexists])
|
||||
|
||||
if test ! "$pythonexists" = "yes"; then
|
||||
AC_MSG_ERROR([
|
||||
Could not link test program to Python. Maybe the main Python library has been
|
||||
installed in some non-standard library path. If so, pass it to configure,
|
||||
via the LDFLAGS environment variable.
|
||||
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
|
||||
============================================================================
|
||||
ERROR!
|
||||
You probably have to install the development version of the Python package
|
||||
for your distribution. The exact name of this package varies among them.
|
||||
============================================================================
|
||||
])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
AC_LANG_POP
|
||||
# turn back to default flags
|
||||
CPPFLAGS="$ac_save_CPPFLAGS"
|
||||
LIBS="$ac_save_LIBS"
|
||||
|
||||
#
|
||||
# all done!
|
||||
#
|
||||
])
|
||||
|
||||
-332
@@ -1,332 +0,0 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro figures out how to build C programs using POSIX threads. It
|
||||
# sets the PTHREAD_LIBS output variable to the threads library and linker
|
||||
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
|
||||
# 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 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 link it with them as well. e.g. you should link with
|
||||
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
|
||||
#
|
||||
# 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"
|
||||
# CC="$PTHREAD_CC"
|
||||
#
|
||||
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
|
||||
# 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
|
||||
# PTHREAD_CFLAGS.
|
||||
#
|
||||
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
|
||||
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
|
||||
# is not found. If ACTION-IF-FOUND is not specified, the default action
|
||||
# will define HAVE_PTHREAD.
|
||||
#
|
||||
# Please let the authors know if this macro fails on any platform, or if
|
||||
# you have any other suggestions or comments. This macro was based on work
|
||||
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
|
||||
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
|
||||
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
|
||||
# grateful for the helpful feedback of numerous users.
|
||||
#
|
||||
# Updated for Autoconf 2.68 by Daniel Richard G.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation, either version 3 of the License, or (at your
|
||||
# option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
# Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program. If not, see <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
|
||||
# scripts that are the output of Autoconf when processing the Macro. You
|
||||
# need not follow the terms of the GNU General Public License when using
|
||||
# or distributing such scripts, even though portions of the text of the
|
||||
# Macro appear in them. The GNU General Public License (GPL) does govern
|
||||
# all other use of the material that constitutes the Autoconf Macro.
|
||||
#
|
||||
# This special exception to the GPL applies to versions of the Autoconf
|
||||
# Macro released by the Autoconf Archive. When you make and distribute a
|
||||
# modified version of the Autoconf Macro, you may extend this special
|
||||
# exception to the GPL to apply to your modified version as well.
|
||||
|
||||
#serial 21
|
||||
|
||||
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
|
||||
AC_DEFUN([AX_PTHREAD], [
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
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 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_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 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
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (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 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 -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# 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)
|
||||
# -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
|
||||
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. (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="-pthreads pthread -mt -pthread $ax_pthread_flags"
|
||||
;;
|
||||
|
||||
darwin*)
|
||||
ax_pthread_flags="-pthread $ax_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Clang doesn't consider unrecognized options an error unless we specify
|
||||
# -Werror. We throw in some extra Clang-specific options to ensure that
|
||||
# this doesn't happen for GCC, which also accepts -Werror.
|
||||
|
||||
AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
|
||||
save_CFLAGS="$CFLAGS"
|
||||
ax_pthread_extra_flags="-Werror"
|
||||
CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[ax_pthread_extra_flags=
|
||||
AC_MSG_RESULT([no])])
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
if test x"$ax_pthread_ok" = xno; then
|
||||
for flag in $ax_pthread_flags; do
|
||||
|
||||
case $flag in
|
||||
none)
|
||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
||||
;;
|
||||
|
||||
-*)
|
||||
AC_MSG_CHECKING([whether pthreads work with $flag])
|
||||
PTHREAD_CFLAGS="$flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
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$flag])
|
||||
PTHREAD_LIBS="-l$flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
save_LIBS="$LIBS"
|
||||
save_CFLAGS="$CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# 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>
|
||||
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);
|
||||
pthread_join(th, 0);
|
||||
pthread_attr_init(&attr);
|
||||
pthread_cleanup_push(routine, 0);
|
||||
pthread_cleanup_pop(0) /* ; */])],
|
||||
[ax_pthread_ok=yes],
|
||||
[])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
AC_MSG_RESULT([$ax_pthread_ok])
|
||||
if test "x$ax_pthread_ok" = xyes; then
|
||||
break;
|
||||
fi
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
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_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_MSG_CHECKING([if more special flags are required for pthreads])
|
||||
flag=no
|
||||
case ${host_os} in
|
||||
aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
|
||||
osf* | hpux*) flag="-D_REENTRANT";;
|
||||
solaris*)
|
||||
if test "$GCC" = "yes"; then
|
||||
flag="-D_REENTRANT"
|
||||
else
|
||||
# TODO: What about Clang on Solaris?
|
||||
flag="-mt -D_REENTRANT"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT([$flag])
|
||||
if test "x$flag" != xno; then
|
||||
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT], [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
|
||||
[[int i = PTHREAD_PRIO_INHERIT;]])],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
|
||||
[ax_cv_PTHREAD_PRIO_INHERIT=no])
|
||||
])
|
||||
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
|
||||
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
# More AIX lossage: compile with *_r variant
|
||||
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"])],
|
||||
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
|
||||
|
||||
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])
|
||||
:
|
||||
else
|
||||
ax_pthread_ok=no
|
||||
$2
|
||||
fi
|
||||
AC_LANG_POP
|
||||
])dnl AX_PTHREAD
|
||||
@@ -1,712 +0,0 @@
|
||||
/*
|
||||
* cachedb/cachedb.c - 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 "config.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "validator/val_neg.h"
|
||||
#include "validator/val_secalgo.h"
|
||||
#include "iterator/iter_utils.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
|
||||
#define CACHEDB_HASHSIZE 256 /* bit hash */
|
||||
|
||||
/** the unit test testframe for cachedb, its module state contains
|
||||
* a cache for a couple queries (in memory). */
|
||||
struct testframe_moddata {
|
||||
/** key for single stored data element, NULL if none */
|
||||
char* stored_key;
|
||||
/** data for single stored data element, NULL if none */
|
||||
uint8_t* stored_data;
|
||||
/** length of stored data */
|
||||
size_t stored_datalen;
|
||||
};
|
||||
|
||||
static int
|
||||
testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_init");
|
||||
cachedb_env->backend_data = (void*)calloc(1,
|
||||
sizeof(struct testframe_moddata));
|
||||
if(!cachedb_env->backend_data) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
testframe_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_deinit");
|
||||
if(!d)
|
||||
return;
|
||||
free(d->stored_key);
|
||||
free(d->stored_data);
|
||||
free(d);
|
||||
}
|
||||
|
||||
static int
|
||||
testframe_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, struct sldns_buffer* result_buffer)
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_lookup of %s", key);
|
||||
if(d->stored_key && strcmp(d->stored_key, key) == 0) {
|
||||
if(d->stored_datalen > sldns_buffer_capacity(result_buffer))
|
||||
return 0; /* too large */
|
||||
verbose(VERB_ALGO, "testframe_lookup found %d bytes",
|
||||
(int)d->stored_datalen);
|
||||
sldns_buffer_clear(result_buffer);
|
||||
sldns_buffer_write(result_buffer, d->stored_data,
|
||||
d->stored_datalen);
|
||||
sldns_buffer_flip(result_buffer);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
testframe_store(struct module_env* env, struct cachedb_env* cachedb_env,
|
||||
char* key, uint8_t* data, size_t data_len)
|
||||
{
|
||||
struct testframe_moddata* d = (struct testframe_moddata*)
|
||||
cachedb_env->backend_data;
|
||||
(void)env;
|
||||
verbose(VERB_ALGO, "testframe_store %s (%d bytes)", key, (int)data_len);
|
||||
|
||||
/* free old data element (if any) */
|
||||
free(d->stored_key);
|
||||
d->stored_key = NULL;
|
||||
free(d->stored_data);
|
||||
d->stored_data = NULL;
|
||||
d->stored_datalen = 0;
|
||||
|
||||
d->stored_data = memdup(data, data_len);
|
||||
if(!d->stored_data) {
|
||||
log_err("out of memory");
|
||||
return;
|
||||
}
|
||||
d->stored_datalen = data_len;
|
||||
d->stored_key = strdup(key);
|
||||
if(!d->stored_key) {
|
||||
free(d->stored_data);
|
||||
d->stored_data = NULL;
|
||||
d->stored_datalen = 0;
|
||||
return;
|
||||
}
|
||||
/* (key,data) successfully stored */
|
||||
}
|
||||
|
||||
/** The testframe backend is for unit tests */
|
||||
static struct cachedb_backend testframe_backend = { "testframe",
|
||||
testframe_init, testframe_deinit, testframe_lookup, testframe_store
|
||||
};
|
||||
|
||||
/** find a particular backend from possible backends */
|
||||
static struct cachedb_backend*
|
||||
cachedb_find_backend(const char* str)
|
||||
{
|
||||
if(strcmp(str, testframe_backend.name) == 0)
|
||||
return &testframe_backend;
|
||||
/* TODO add more backends here */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** apply configuration to cachedb module 'global' state */
|
||||
static int
|
||||
cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
|
||||
{
|
||||
const char* backend_str = "testframe"; /* TODO get from cfg */
|
||||
if(backend_str && backend_str[0]) {
|
||||
cachedb_env->backend = cachedb_find_backend(backend_str);
|
||||
if(!cachedb_env->backend) {
|
||||
log_err("cachedb: cannot find backend name '%s",
|
||||
backend_str);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* TODO see if more configuration needs to be applied or not */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
cachedb_init(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* cachedb_env = (struct cachedb_env*)calloc(1,
|
||||
sizeof(struct cachedb_env));
|
||||
if(!cachedb_env) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
env->modinfo[id] = (void*)cachedb_env;
|
||||
if(!cachedb_apply_cfg(cachedb_env, env->cfg)) {
|
||||
log_err("cachedb: could not apply configuration settings.");
|
||||
return 0;
|
||||
}
|
||||
/* see if a backend is selected */
|
||||
if(!cachedb_env->backend || !cachedb_env->backend->name)
|
||||
return 1;
|
||||
if(!(*cachedb_env->backend->init)(env, cachedb_env)) {
|
||||
log_err("cachedb: could not init %s backend",
|
||||
cachedb_env->backend->name);
|
||||
return 0;
|
||||
}
|
||||
cachedb_env->enabled = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_deinit(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* cachedb_env;
|
||||
if(!env || !env->modinfo[id])
|
||||
return;
|
||||
cachedb_env = (struct cachedb_env*)env->modinfo[id];
|
||||
/* free contents */
|
||||
/* TODO */
|
||||
if(cachedb_env->enabled) {
|
||||
(*cachedb_env->backend->deinit)(env, cachedb_env);
|
||||
}
|
||||
|
||||
free(cachedb_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
/** new query for cachedb */
|
||||
static int
|
||||
cachedb_new(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct cachedb_qstate* iq = (struct cachedb_qstate*)regional_alloc(
|
||||
qstate->region, sizeof(struct cachedb_qstate));
|
||||
qstate->minfo[id] = iq;
|
||||
if(!iq)
|
||||
return 0;
|
||||
memset(iq, 0, sizeof(*iq));
|
||||
/* initialise it */
|
||||
/* TODO */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an error
|
||||
* @param qstate: our query state
|
||||
* @param id: module id
|
||||
* @param rcode: error code (DNS errcode).
|
||||
* @return: 0 for use by caller, to make notation easy, like:
|
||||
* return error_response(..).
|
||||
*/
|
||||
static int
|
||||
error_response(struct module_qstate* qstate, int id, int rcode)
|
||||
{
|
||||
verbose(VERB_QUERY, "return error response %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, rcode)->name:"??");
|
||||
qstate->return_rcode = rcode;
|
||||
qstate->return_msg = NULL;
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash the query name, type, class and dbacess-secret into lookup buffer.
|
||||
* @param qstate: query state with query info
|
||||
* and env->cfg with secret.
|
||||
* @param buf: returned buffer with hash to lookup
|
||||
* @param len: length of the buffer.
|
||||
*/
|
||||
static void
|
||||
calc_hash(struct module_qstate* qstate, char* buf, size_t len)
|
||||
{
|
||||
uint8_t clear[1024];
|
||||
size_t clen = 0;
|
||||
uint8_t hash[CACHEDB_HASHSIZE/8];
|
||||
const char* hex = "0123456789ABCDEF";
|
||||
const char* secret = "default"; /* TODO: from qstate->env->cfg */
|
||||
size_t i;
|
||||
|
||||
/* copy the hash info into the clear buffer */
|
||||
if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
|
||||
memmove(clear+clen, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len);
|
||||
clen += qstate->qinfo.qname_len;
|
||||
}
|
||||
if(clen + 4 < sizeof(clear)) {
|
||||
uint16_t t = htons(qstate->qinfo.qtype);
|
||||
uint16_t c = htons(qstate->qinfo.qclass);
|
||||
memmove(clear+clen, &t, 2);
|
||||
memmove(clear+clen+2, &c, 2);
|
||||
clen += 4;
|
||||
}
|
||||
if(secret && secret[0] && clen + strlen(secret) < sizeof(clear)) {
|
||||
memmove(clear+clen, secret, strlen(secret));
|
||||
clen += strlen(secret);
|
||||
}
|
||||
|
||||
/* hash the buffer */
|
||||
secalgo_hash_sha256(clear, clen, hash);
|
||||
memset(clear, 0, clen);
|
||||
|
||||
/* hex encode output for portability (some online dbs need
|
||||
* no nulls, no control characters, and so on) */
|
||||
log_assert(len >= sizeof(hash)*2 + 1);
|
||||
(void)len;
|
||||
for(i=0; i<sizeof(hash); i++) {
|
||||
buf[i*2] = hex[(hash[i]&0xf0)>>4];
|
||||
buf[i*2+1] = hex[hash[i]&0x0f];
|
||||
}
|
||||
buf[sizeof(hash)*2] = 0;
|
||||
}
|
||||
|
||||
/** convert data from return_msg into the data buffer */
|
||||
static int
|
||||
prep_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
uint64_t timestamp, expiry;
|
||||
size_t oldlim;
|
||||
struct edns_data edns;
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
edns.edns_present = 1;
|
||||
edns.bits = EDNS_DO;
|
||||
edns.ext_rcode = 0;
|
||||
edns.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
|
||||
if(!qstate->return_msg || !qstate->return_msg->rep)
|
||||
return 0;
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
if(!reply_info_answer_encode(&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->query_flags,
|
||||
buf, 0, 1, qstate->env->scratch, 65535, &edns, 1, 0))
|
||||
return 0;
|
||||
|
||||
/* TTLs in the return_msg are relative to time(0) so we have to
|
||||
* store that, we also store the smallest ttl in the packet+time(0)
|
||||
* as the packet expiry time */
|
||||
/* qstate->return_msg->rep->ttl contains that relative shortest ttl */
|
||||
timestamp = (uint64_t)*qstate->env->now;
|
||||
expiry = timestamp + (uint64_t)qstate->return_msg->rep->ttl;
|
||||
timestamp = htobe64(timestamp);
|
||||
expiry = htobe64(expiry);
|
||||
oldlim = sldns_buffer_limit(buf);
|
||||
if(oldlim + sizeof(timestamp)+sizeof(expiry) >=
|
||||
sldns_buffer_capacity(buf))
|
||||
return 0; /* doesn't fit. */
|
||||
sldns_buffer_set_limit(buf, oldlim + sizeof(timestamp)+sizeof(expiry));
|
||||
sldns_buffer_write_at(buf, oldlim, ×tamp, sizeof(timestamp));
|
||||
sldns_buffer_write_at(buf, oldlim+sizeof(timestamp), &expiry,
|
||||
sizeof(expiry));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** check expiry, return true if matches OK */
|
||||
static int
|
||||
good_expiry_and_qinfo(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
uint64_t expiry;
|
||||
/* the expiry time is the last bytes of the buffer */
|
||||
if(sldns_buffer_limit(buf) < sizeof(expiry))
|
||||
return 0;
|
||||
sldns_buffer_read_at(buf, sldns_buffer_limit(buf)-sizeof(expiry),
|
||||
&expiry, sizeof(expiry));
|
||||
expiry = be64toh(expiry);
|
||||
|
||||
if((time_t)expiry < *qstate->env->now)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** convert dns message in buffer to return_msg */
|
||||
static int
|
||||
parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
|
||||
{
|
||||
struct msg_parse* prs;
|
||||
struct edns_data edns;
|
||||
uint64_t timestamp, expiry;
|
||||
time_t adjust;
|
||||
size_t lim = sldns_buffer_limit(buf);
|
||||
if(lim < LDNS_HEADER_SIZE+sizeof(timestamp)+sizeof(expiry))
|
||||
return 0; /* too short */
|
||||
|
||||
/* remove timestamp and expiry from end */
|
||||
sldns_buffer_read_at(buf, lim-sizeof(expiry), &expiry, sizeof(expiry));
|
||||
sldns_buffer_read_at(buf, lim-sizeof(expiry)-sizeof(timestamp),
|
||||
×tamp, sizeof(timestamp));
|
||||
expiry = be64toh(expiry);
|
||||
timestamp = be64toh(timestamp);
|
||||
|
||||
/* parse DNS packet */
|
||||
regional_free_all(qstate->env->scratch);
|
||||
prs = (struct msg_parse*)regional_alloc(qstate->env->scratch,
|
||||
sizeof(struct msg_parse));
|
||||
if(!prs)
|
||||
return 0; /* out of memory */
|
||||
memset(prs, 0, sizeof(*prs));
|
||||
memset(&edns, 0, sizeof(edns));
|
||||
sldns_buffer_set_limit(buf, lim - sizeof(expiry)-sizeof(timestamp));
|
||||
if(parse_packet(buf, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) {
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
return 0;
|
||||
}
|
||||
if(parse_extract_edns(prs, &edns, qstate->env->scratch) !=
|
||||
LDNS_RCODE_NOERROR) {
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qstate->return_msg = dns_alloc_msg(buf, prs, qstate->region);
|
||||
sldns_buffer_set_limit(buf, lim);
|
||||
if(!qstate->return_msg)
|
||||
return 0;
|
||||
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
|
||||
/* see how much of the TTL expired, and remove it */
|
||||
adjust = *qstate->env->now - (time_t)timestamp;
|
||||
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
|
||||
/*adjust_msg(qstate->return_msg, adjust);*/
|
||||
/* TODO:
|
||||
msg->rep->ttl = r->ttl - adjust;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
for(i=0; i<d->count + d->rrsig_count; i++) {
|
||||
if(d->rr_ttl[i] < adjust)
|
||||
d->rr_ttl[i] = 0;
|
||||
else d->rr_ttl[i] -= adjust;
|
||||
}
|
||||
if(d->ttl < adjust)
|
||||
d->ttl = 0;
|
||||
else d->ttl -= adjust;
|
||||
*/
|
||||
/* TODO */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup the qstate.qinfo in extcache, store in qstate.return_msg.
|
||||
* return true if lookup was successful.
|
||||
*/
|
||||
static int
|
||||
cachedb_extcache_lookup(struct module_qstate* qstate, struct cachedb_env* ie)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(qstate, key, sizeof(key));
|
||||
|
||||
/* call backend to fetch data for key into scratch buffer */
|
||||
if( !(*ie->backend->lookup)(qstate->env, ie, key,
|
||||
qstate->env->scratch_buffer)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check expiry date and check if query-data matches */
|
||||
if( !good_expiry_and_qinfo(qstate, qstate->env->scratch_buffer) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse dns message into return_msg */
|
||||
if( !parse_data(qstate, qstate->env->scratch_buffer) ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the qstate.return_msg in extcache for key qstate.info
|
||||
*/
|
||||
static void
|
||||
cachedb_extcache_store(struct module_qstate* qstate, struct cachedb_env* ie)
|
||||
{
|
||||
char key[(CACHEDB_HASHSIZE/8)*2+1];
|
||||
calc_hash(qstate, key, sizeof(key));
|
||||
|
||||
/* prepare data in scratch buffer */
|
||||
if(!prep_data(qstate, qstate->env->scratch_buffer))
|
||||
return;
|
||||
|
||||
/* call backend */
|
||||
(*ie->backend->store)(qstate->env, ie, key,
|
||||
sldns_buffer_begin(qstate->env->scratch_buffer),
|
||||
sldns_buffer_limit(qstate->env->scratch_buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* See if unbound's internal cache can answer the query
|
||||
*/
|
||||
static int
|
||||
cachedb_intcache_lookup(struct module_qstate* qstate)
|
||||
{
|
||||
struct dns_msg* msg;
|
||||
msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
|
||||
qstate->qinfo.qname_len, qstate->qinfo.qtype,
|
||||
qstate->qinfo.qclass, qstate->query_flags,
|
||||
qstate->region, qstate->env->scratch);
|
||||
if(!msg && qstate->env->neg_cache) {
|
||||
/* lookup in negative cache; may result in
|
||||
* NOERROR/NODATA or NXDOMAIN answers that need validation */
|
||||
msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
|
||||
qstate->region, qstate->env->rrset_cache,
|
||||
qstate->env->scratch_buffer,
|
||||
*qstate->env->now, 1/*add SOA*/, NULL);
|
||||
}
|
||||
if(!msg)
|
||||
return 0;
|
||||
/* this is the returned msg */
|
||||
qstate->return_rcode = LDNS_RCODE_NOERROR;
|
||||
qstate->return_msg = msg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store query into the internal cache of unbound.
|
||||
*/
|
||||
static void
|
||||
cachedb_intcache_store(struct module_qstate* qstate)
|
||||
{
|
||||
if(!qstate->return_msg)
|
||||
return;
|
||||
(void)dns_cache_store(qstate->env, &qstate->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
|
||||
qstate->region, qstate->query_flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a cachedb module event with a query
|
||||
* @param qstate: query state (from the mesh), passed between modules.
|
||||
* contains qstate->env module environment with global caches and so on.
|
||||
* @param iq: query state specific for this module. per-query.
|
||||
* @param ie: environment specific for this module. global.
|
||||
* @param id: module id.
|
||||
*/
|
||||
static void
|
||||
cachedb_handle_query(struct module_qstate* qstate,
|
||||
struct cachedb_qstate* ATTR_UNUSED(iq),
|
||||
struct cachedb_env* ie, int id)
|
||||
{
|
||||
/* check if we are enabled, and skip if so */
|
||||
if(!ie->enabled) {
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
if(qstate->blacklist || qstate->no_cache_lookup) {
|
||||
/* cache is blacklisted or we are instructed from edns to not look */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
}
|
||||
|
||||
/* lookup inside unbound's internal cache */
|
||||
if(cachedb_intcache_lookup(qstate)) {
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
if(qstate->return_msg->rep)
|
||||
log_dns_msg("cachedb internal cache lookup",
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
else log_info("cachedb internal cache lookup: rcode %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)?
|
||||
sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name:"??");
|
||||
}
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* ask backend cache to see if we have data */
|
||||
if(cachedb_extcache_lookup(qstate, ie)) {
|
||||
if(verbosity >= VERB_ALGO)
|
||||
log_dns_msg(ie->backend->name,
|
||||
&qstate->return_msg->qinfo,
|
||||
qstate->return_msg->rep);
|
||||
/* store this result in internal cache */
|
||||
cachedb_intcache_store(qstate);
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* no cache fetches */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a cachedb module event with a response from the iterator.
|
||||
* @param qstate: query state (from the mesh), passed between modules.
|
||||
* contains qstate->env module environment with global caches and so on.
|
||||
* @param iq: query state specific for this module. per-query.
|
||||
* @param ie: environment specific for this module. global.
|
||||
* @param id: module id.
|
||||
*/
|
||||
static void
|
||||
cachedb_handle_response(struct module_qstate* qstate,
|
||||
struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
|
||||
{
|
||||
/* check if we are not enabled or instructed to not cache, and skip */
|
||||
if(!ie->enabled || qstate->no_cache_store) {
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
/* store the item into the backend cache */
|
||||
cachedb_extcache_store(qstate, ie);
|
||||
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
struct cachedb_env* ie = (struct cachedb_env*)qstate->env->modinfo[id];
|
||||
struct cachedb_qstate* iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
verbose(VERB_QUERY, "cachedb[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]), strmodulevent(event));
|
||||
if(iq) log_query_info(VERB_QUERY, "cachedb operate: query",
|
||||
&qstate->qinfo);
|
||||
|
||||
/* perform cachedb state machine */
|
||||
if((event == module_event_new || event == module_event_pass) &&
|
||||
iq == NULL) {
|
||||
if(!cachedb_new(qstate, id)) {
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
}
|
||||
if(iq && (event == module_event_pass || event == module_event_new)) {
|
||||
cachedb_handle_query(qstate, iq, ie, id);
|
||||
return;
|
||||
}
|
||||
if(iq && (event == module_event_moddone)) {
|
||||
cachedb_handle_response(qstate, iq, ie, id);
|
||||
return;
|
||||
}
|
||||
if(iq && outbound) {
|
||||
/* cachedb does not need to process responses at this time
|
||||
* ignore it.
|
||||
cachedb_process_response(qstate, iq, ie, id, outbound, event);
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if(event == module_event_error) {
|
||||
verbose(VERB_ALGO, "got called with event error, giving up");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
return;
|
||||
}
|
||||
if(!iq && (event == module_event_moddone)) {
|
||||
/* during priming, module done but we never started */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
}
|
||||
|
||||
log_err("bad event for cachedb");
|
||||
(void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_inform_super(struct module_qstate* ATTR_UNUSED(qstate),
|
||||
int ATTR_UNUSED(id), struct module_qstate* ATTR_UNUSED(super))
|
||||
{
|
||||
/* cachedb does not use subordinate requests at this time */
|
||||
verbose(VERB_ALGO, "cachedb inform_super was called");
|
||||
}
|
||||
|
||||
void
|
||||
cachedb_clear(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct cachedb_qstate* iq;
|
||||
if(!qstate)
|
||||
return;
|
||||
iq = (struct cachedb_qstate*)qstate->minfo[id];
|
||||
if(iq) {
|
||||
/* free contents of iq */
|
||||
/* TODO */
|
||||
}
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
size_t
|
||||
cachedb_get_mem(struct module_env* env, int id)
|
||||
{
|
||||
struct cachedb_env* ie = (struct cachedb_env*)env->modinfo[id];
|
||||
if(!ie)
|
||||
return 0;
|
||||
return sizeof(*ie); /* TODO - more mem */
|
||||
}
|
||||
|
||||
/**
|
||||
* The cachedb function block
|
||||
*/
|
||||
static struct module_func_block cachedb_block = {
|
||||
"cachedb",
|
||||
&cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
cachedb_get_funcblock(void)
|
||||
{
|
||||
return &cachedb_block;
|
||||
}
|
||||
#endif /* USE_CACHEDB */
|
||||
@@ -1,110 +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;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/** 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);
|
||||
|
||||
@@ -1,67 +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
|
||||
#include "util/locks.h"
|
||||
|
||||
void _ARC4_LOCK(void);
|
||||
void _ARC4_UNLOCK(void);
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
void _ARC4_LOCK(void)
|
||||
{
|
||||
}
|
||||
|
||||
void _ARC4_UNLOCK(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);
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
@@ -1,236 +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)
|
||||
|
||||
/* 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);
|
||||
|
||||
static inline void
|
||||
_rs_init(u_char *buf, size_t n)
|
||||
{
|
||||
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];
|
||||
|
||||
if (getentropy(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));
|
||||
|
||||
rs->rs_count = 1600000;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/* taken from ldns 1.6.1 */
|
||||
#include "config.h"
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include "util/locks.h"
|
||||
|
||||
/** the lock for ctime buffer */
|
||||
static lock_basic_type ctime_lock;
|
||||
/** has it been inited */
|
||||
static int ctime_r_init = 0;
|
||||
|
||||
/** cleanup ctime_r on exit */
|
||||
static void
|
||||
ctime_r_cleanup(void)
|
||||
{
|
||||
if(ctime_r_init) {
|
||||
ctime_r_init = 0;
|
||||
lock_basic_destroy(&ctime_lock);
|
||||
}
|
||||
}
|
||||
|
||||
char *ctime_r(const time_t *timep, char *buf)
|
||||
{
|
||||
char* result;
|
||||
if(!ctime_r_init) {
|
||||
/* still small race where this init can be done twice,
|
||||
* which is mostly harmless */
|
||||
ctime_r_init = 1;
|
||||
lock_basic_init(&ctime_lock);
|
||||
atexit(&ctime_r_cleanup);
|
||||
}
|
||||
lock_basic_lock(&ctime_lock);
|
||||
result = ctime(timep);
|
||||
if(buf && result) {
|
||||
if(strlen(result) > 10 && result[7]==' ' && result[8]=='0')
|
||||
result[8]=' '; /* fix error in windows ctime */
|
||||
strcpy(buf, result);
|
||||
}
|
||||
lock_basic_unlock(&ctime_lock);
|
||||
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,560 +0,0 @@
|
||||
/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck 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"
|
||||
|
||||
/*
|
||||
#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 HAVE_SYS_SYSCTL_H
|
||||
#include <sys/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 <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(HAVE_SSL)
|
||||
#include <openssl/sha.h>
|
||||
#elif defined(HAVE_NETTLE)
|
||||
#include <nettle/sha.h>
|
||||
#endif
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sysctl.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)
|
||||
|
||||
#if defined(HAVE_SSL)
|
||||
#define CRYPTO_SHA512_CTX SHA512_CTX
|
||||
#define CRYPTO_SHA512_INIT(x) SHA512_Init(x)
|
||||
#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c)
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
#elif defined(HAVE_NETTLE)
|
||||
#define CRYPTO_SHA512_CTX struct sha512_ctx
|
||||
#define CRYPTO_SHA512_INIT(x) sha512_init(x)
|
||||
#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
|
||||
#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
|
||||
#define HF(x) (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x)))
|
||||
#endif
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
static int getentropy_getrandom(void *buf, size_t len);
|
||||
#endif
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
#ifdef SYS__sysctl
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
/*
|
||||
* Try descriptor-less getrandom()
|
||||
*/
|
||||
ret = getentropy_getrandom(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
if (errno != ENOSYS)
|
||||
return (-1);
|
||||
#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
|
||||
* 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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
static int
|
||||
getentropy_getrandom(void *buf, size_t len)
|
||||
{
|
||||
int pre_errno = errno;
|
||||
int ret;
|
||||
if (len > 256)
|
||||
return (-1);
|
||||
do {
|
||||
ret = syscall(SYS_getrandom, buf, len, 0);
|
||||
} 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);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
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;
|
||||
}
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
sysctlfailed:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
#endif /* SYS__sysctl */
|
||||
|
||||
static 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;
|
||||
struct rusage ru;
|
||||
sigset_t sigset;
|
||||
struct stat st;
|
||||
CRYPTO_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;
|
||||
CRYPTO_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);
|
||||
|
||||
if (!faster) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
(void) nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
HX(sigpending(&sigset) == -1, sigset);
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
HD(p); /* an addr on stack */
|
||||
p = (char *)&errno;
|
||||
HD(p); /* the addr of errno */
|
||||
|
||||
if (i == 0) {
|
||||
struct sockaddr_storage ss;
|
||||
struct statvfs stvfs;
|
||||
struct termios tios;
|
||||
struct statfs stfs;
|
||||
socklen_t ssl;
|
||||
off_t off;
|
||||
|
||||
/*
|
||||
* Prime-sized mappings encourage fragmentation;
|
||||
* thus exposing some address entropy.
|
||||
*/
|
||||
struct mm {
|
||||
size_t npg;
|
||||
void *p;
|
||||
} mm[] = {
|
||||
{ 17, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 11, MAP_FAILED }, { 2, MAP_FAILED },
|
||||
{ 5, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 7, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
{ 57, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 131, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
};
|
||||
|
||||
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
|
||||
HX(mm[m].p = mmap(NULL,
|
||||
mm[m].npg * pgs,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANON, -1,
|
||||
(off_t)0), mm[m].p);
|
||||
if (mm[m].p != MAP_FAILED) {
|
||||
size_t mo;
|
||||
|
||||
/* Touch some memory... */
|
||||
p = mm[m].p;
|
||||
mo = cnt %
|
||||
(mm[m].npg * pgs - 1);
|
||||
p[mo] = 1;
|
||||
cnt += (int)((long)(mm[m].p)
|
||||
/ pgs);
|
||||
}
|
||||
|
||||
/* Check cnts and times... */
|
||||
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 /* HAVE_GETAUXVAL */
|
||||
|
||||
CRYPTO_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,432 +0,0 @@
|
||||
/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 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.
|
||||
*/
|
||||
#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/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>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/ip_var.h>
|
||||
#include <netinet/tcp_var.h>
|
||||
#include <netinet/udp_var.h>
|
||||
#include <CommonCrypto/CommonDigest.h>
|
||||
#define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
|
||||
#define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
|
||||
#define SHA512_Final(xxx, yyy) (CC_SHA512_Final((xxx), (yyy)))
|
||||
#define SHA512_CTX CC_SHA512_CTX
|
||||
#define SHA512_DIGEST_LENGTH CC_SHA512_DIGEST_LENGTH
|
||||
|
||||
#define REPEAT 5
|
||||
#define min(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define HX(a, b) \
|
||||
do { \
|
||||
if ((a)) \
|
||||
HD(errno); \
|
||||
else \
|
||||
HD(b); \
|
||||
} while (0)
|
||||
|
||||
#define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
|
||||
#define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
|
||||
#define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
|
||||
|
||||
int getentropy(void *buf, size_t len);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
extern int main(int, char *argv[]);
|
||||
#endif
|
||||
static int gotdata(char *buf, size_t len);
|
||||
static int getentropy_urandom(void *buf, size_t len);
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (len > 256) {
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic sanity checking; wish we could do better.
|
||||
*/
|
||||
static int
|
||||
gotdata(char *buf, size_t len)
|
||||
{
|
||||
char any_set = 0;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
any_set |= buf[i];
|
||||
if (any_set == 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
struct stat st;
|
||||
size_t i;
|
||||
int fd, flags;
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_NOFOLLOW
|
||||
flags |= O_NOFOLLOW;
|
||||
#endif
|
||||
#ifdef O_CLOEXEC
|
||||
flags |= O_CLOEXEC;
|
||||
#endif
|
||||
fd = open("/dev/urandom", flags, 0);
|
||||
if (fd == -1) {
|
||||
if (errno == EINTR)
|
||||
goto start;
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef O_CLOEXEC
|
||||
fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
/* Lightly verify that the device node looks sane */
|
||||
if (fstat(fd, &st) == -1 || !S_ISCHR(st.st_mode)) {
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char*)buf + i, wanted);
|
||||
|
||||
if (ret == -1) {
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
i += ret;
|
||||
}
|
||||
close(fd);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
nodevrandom:
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
|
||||
static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
|
||||
static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
|
||||
static int kmib[] = { CTL_KERN, KERN_USRSTACK };
|
||||
static int hwmib[] = { CTL_HW, HW_USERMEM };
|
||||
|
||||
static int
|
||||
getentropy_fallback(void *buf, size_t len)
|
||||
{
|
||||
uint8_t results[SHA512_DIGEST_LENGTH];
|
||||
int save_errno = errno, e, pgs = getpagesize(), faster = 0, repeat;
|
||||
static int cnt;
|
||||
struct timespec ts;
|
||||
struct timeval tv;
|
||||
struct rusage ru;
|
||||
sigset_t sigset;
|
||||
struct stat st;
|
||||
SHA512_CTX ctx;
|
||||
static pid_t lastpid;
|
||||
pid_t pid;
|
||||
size_t i, ii, m;
|
||||
char *p;
|
||||
struct tcpstat tcpstat;
|
||||
struct udpstat udpstat;
|
||||
struct ipstat ipstat;
|
||||
u_int64_t mach_time;
|
||||
unsigned int idata;
|
||||
void *addr;
|
||||
|
||||
pid = getpid();
|
||||
if (lastpid == pid) {
|
||||
faster = 1;
|
||||
repeat = 2;
|
||||
} else {
|
||||
faster = 0;
|
||||
lastpid = pid;
|
||||
repeat = REPEAT;
|
||||
}
|
||||
for (i = 0; i < len; ) {
|
||||
int j;
|
||||
SHA512_Init(&ctx);
|
||||
for (j = 0; j < repeat; j++) {
|
||||
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
|
||||
if (e != -1) {
|
||||
cnt += (int)tv.tv_sec;
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
mach_time = mach_absolute_time();
|
||||
HD(mach_time);
|
||||
|
||||
ii = sizeof(addr);
|
||||
HX(sysctl(kmib, sizeof(kmib) / sizeof(kmib[0]),
|
||||
&addr, &ii, NULL, 0) == -1, addr);
|
||||
|
||||
ii = sizeof(idata);
|
||||
HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
|
||||
&idata, &ii, NULL, 0) == -1, idata);
|
||||
|
||||
ii = sizeof(tcpstat);
|
||||
HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
|
||||
&tcpstat, &ii, NULL, 0) == -1, tcpstat);
|
||||
|
||||
ii = sizeof(udpstat);
|
||||
HX(sysctl(udpmib, sizeof(udpmib) / sizeof(udpmib[0]),
|
||||
&udpstat, &ii, NULL, 0) == -1, udpstat);
|
||||
|
||||
ii = sizeof(ipstat);
|
||||
HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
|
||||
&ipstat, &ii, NULL, 0) == -1, ipstat);
|
||||
|
||||
HX((pid = getpid()) == -1, pid);
|
||||
HX((pid = getsid(pid)) == -1, pid);
|
||||
HX((pid = getppid()) == -1, pid);
|
||||
HX((pid = getpgid(0)) == -1, pid);
|
||||
HX((e = getpriority(0, 0)) == -1, e);
|
||||
|
||||
if (!faster) {
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
(void) nanosleep(&ts, NULL);
|
||||
}
|
||||
|
||||
HX(sigpending(&sigset) == -1, sigset);
|
||||
HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
|
||||
sigset);
|
||||
|
||||
#ifdef CAN_REFERENCE_MAIN
|
||||
HF(main); /* an addr in program */
|
||||
#endif
|
||||
HF(getentropy); /* an addr in this library */
|
||||
HF(printf); /* an addr in libc */
|
||||
p = (char *)&p;
|
||||
HD(p); /* an addr on stack */
|
||||
p = (char *)&errno;
|
||||
HD(p); /* the addr of errno */
|
||||
|
||||
if (i == 0) {
|
||||
struct sockaddr_storage ss;
|
||||
struct statvfs stvfs;
|
||||
struct termios tios;
|
||||
struct statfs stfs;
|
||||
socklen_t ssl;
|
||||
off_t off;
|
||||
|
||||
/*
|
||||
* Prime-sized mappings encourage fragmentation;
|
||||
* thus exposing some address entropy.
|
||||
*/
|
||||
struct mm {
|
||||
size_t npg;
|
||||
void *p;
|
||||
} mm[] = {
|
||||
{ 17, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 11, MAP_FAILED }, { 2, MAP_FAILED },
|
||||
{ 5, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 7, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
{ 57, MAP_FAILED }, { 3, MAP_FAILED },
|
||||
{ 131, MAP_FAILED }, { 1, MAP_FAILED },
|
||||
};
|
||||
|
||||
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
|
||||
HX(mm[m].p = mmap(NULL,
|
||||
mm[m].npg * pgs,
|
||||
PROT_READ|PROT_WRITE,
|
||||
MAP_PRIVATE|MAP_ANON, -1,
|
||||
(off_t)0), mm[m].p);
|
||||
if (mm[m].p != MAP_FAILED) {
|
||||
size_t mo;
|
||||
|
||||
/* Touch some memory... */
|
||||
p = mm[m].p;
|
||||
mo = cnt %
|
||||
(mm[m].npg * pgs - 1);
|
||||
p[mo] = 1;
|
||||
cnt += (int)((long)(mm[m].p)
|
||||
/ pgs);
|
||||
}
|
||||
|
||||
/* Check cnts and times... */
|
||||
mach_time = mach_absolute_time();
|
||||
HD(mach_time);
|
||||
cnt += (int)mach_time;
|
||||
|
||||
HX((e = getrusage(RUSAGE_SELF,
|
||||
&ru)) == -1, ru);
|
||||
if (e != -1) {
|
||||
cnt += (int)ru.ru_utime.tv_sec;
|
||||
cnt += (int)ru.ru_utime.tv_usec;
|
||||
}
|
||||
}
|
||||
|
||||
for (m = 0; m < sizeof mm/sizeof(mm[0]); m++) {
|
||||
if (mm[m].p != MAP_FAILED)
|
||||
munmap(mm[m].p, mm[m].npg * pgs);
|
||||
mm[m].p = MAP_FAILED;
|
||||
}
|
||||
|
||||
HX(stat(".", &st) == -1, st);
|
||||
HX(statvfs(".", &stvfs) == -1, stvfs);
|
||||
HX(statfs(".", &stfs) == -1, stfs);
|
||||
|
||||
HX(stat("/", &st) == -1, st);
|
||||
HX(statvfs("/", &stvfs) == -1, stvfs);
|
||||
HX(statfs("/", &stfs) == -1, stfs);
|
||||
|
||||
HX((e = fstat(0, &st)) == -1, st);
|
||||
if (e == -1) {
|
||||
if (S_ISREG(st.st_mode) ||
|
||||
S_ISFIFO(st.st_mode) ||
|
||||
S_ISSOCK(st.st_mode)) {
|
||||
HX(fstatvfs(0, &stvfs) == -1,
|
||||
stvfs);
|
||||
HX(fstatfs(0, &stfs) == -1,
|
||||
stfs);
|
||||
HX((off = lseek(0, (off_t)0,
|
||||
SEEK_CUR)) < 0, off);
|
||||
}
|
||||
if (S_ISCHR(st.st_mode)) {
|
||||
HX(tcgetattr(0, &tios) == -1,
|
||||
tios);
|
||||
} else if (S_ISSOCK(st.st_mode)) {
|
||||
memset(&ss, 0, sizeof ss);
|
||||
ssl = sizeof(ss);
|
||||
HX(getpeername(0,
|
||||
(void *)&ss, &ssl) == -1,
|
||||
ss);
|
||||
}
|
||||
}
|
||||
|
||||
HX((e = getrusage(RUSAGE_CHILDREN,
|
||||
&ru)) == -1, ru);
|
||||
if (e != -1) {
|
||||
cnt += (int)ru.ru_utime.tv_sec;
|
||||
cnt += (int)ru.ru_utime.tv_usec;
|
||||
}
|
||||
} else {
|
||||
/* Subsequent hashes absorb previous result */
|
||||
HD(results);
|
||||
}
|
||||
|
||||
HX((e = gettimeofday(&tv, NULL)) == -1, tv);
|
||||
if (e != -1) {
|
||||
cnt += (int)tv.tv_sec;
|
||||
cnt += (int)tv.tv_usec;
|
||||
}
|
||||
|
||||
HD(cnt);
|
||||
}
|
||||
|
||||
SHA512_Final(results, &ctx);
|
||||
memcpy((char*)buf + i, results, min(sizeof(results), len - i));
|
||||
i += min(sizeof(results), len - i);
|
||||
}
|
||||
memset(results, 0, sizeof results);
|
||||
if (gotdata(buf, len) == 0) {
|
||||
errno = save_errno;
|
||||
return 0; /* satisfied */
|
||||
}
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 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.
|
||||
*/
|
||||
#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,56 +0,0 @@
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* 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 <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
|
||||
|
||||
@@ -135,9 +135,7 @@ inet_ntop6(const u_char *src, char *dst, size_t size)
|
||||
for (i = 0; i < IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
best.len = 0;
|
||||
cur.base = -1;
|
||||
cur.len = 0;
|
||||
for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
|
||||
@@ -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
-2
@@ -1,8 +1,11 @@
|
||||
/* Just a replacement, if the original malloc is not
|
||||
GNU-compliant. See autoconf documentation. */
|
||||
|
||||
#include "config.h"
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#undef malloc
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
void *malloc ();
|
||||
@@ -11,7 +14,7 @@ void *malloc ();
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
void *
|
||||
rpl_malloc_unbound (size_t n)
|
||||
rpl_malloc (size_t n)
|
||||
{
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* memcmp.c: memcmp compat implementation.
|
||||
*
|
||||
* Copyright (c) 2010, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* See LICENSE for the license.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
int memcmp(const void *x, const void *y, size_t n);
|
||||
|
||||
int memcmp(const void *x, const void *y, size_t n)
|
||||
{
|
||||
const uint8_t* x8 = (const uint8_t*)x;
|
||||
const uint8_t* y8 = (const uint8_t*)y;
|
||||
size_t i;
|
||||
for(i=0; i<n; i++) {
|
||||
if(x8[i] < y8[i])
|
||||
return -1;
|
||||
else if(x8[i] > y8[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* memcmp.h: undef memcmp for compat.
|
||||
*
|
||||
* Copyright (c) 2012, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* See LICENSE for the license.
|
||||
*/
|
||||
#ifndef COMPAT_MEMCMP_H
|
||||
#define COMPAT_MEMCMP_H
|
||||
|
||||
#ifdef memcmp
|
||||
/* undef here otherwise autoheader messes it up in config.h */
|
||||
# undef memcmp
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_MEMCMP_H */
|
||||
+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;
|
||||
}
|
||||
+726
-991
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -1,345 +0,0 @@
|
||||
/** strptime workaround (for oa macos leopard)
|
||||
* This strptime follows the man strptime (2001-11-12)
|
||||
* conforming to SUSv2, POSIX.1-2001
|
||||
*
|
||||
* This very simple version of strptime has no:
|
||||
* - E alternatives
|
||||
* - O alternatives
|
||||
* - Glibc additions
|
||||
* - Does not process week numbers
|
||||
* - Does not properly processes year day
|
||||
*
|
||||
* LICENSE
|
||||
* Copyright (c) 2008, NLnet Labs, Matthijs Mekking
|
||||
* 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"
|
||||
|
||||
#ifndef HAVE_CONFIG_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifndef STRPTIME_WORKS
|
||||
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char *abb_weekdays[] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
|
||||
};
|
||||
static const char *full_weekdays[] = {
|
||||
"Sunday", "Monday", "Tuesday", "Wednesday",
|
||||
"Thursday", "Friday", "Saturday", NULL
|
||||
};
|
||||
static const char *abb_months[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
|
||||
};
|
||||
static const char *full_months[] = {
|
||||
"January", "February", "March", "April", "May", "June",
|
||||
"July", "August", "September", "October", "November", "December", NULL
|
||||
};
|
||||
static const char *ampm[] = {
|
||||
"am", "pm", NULL
|
||||
};
|
||||
|
||||
static int
|
||||
match_string(const char **buf, const char **strs)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; strs[i] != NULL; i++) {
|
||||
int len = strlen(strs[i]);
|
||||
if (strncasecmp (*buf, strs[i], len) == 0) {
|
||||
*buf += len;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
str2int(const char **buf, int max)
|
||||
{
|
||||
int ret=0, count=0;
|
||||
|
||||
while (*buf[0] != '\0' && isdigit((unsigned char)*buf[0]) && count<max) {
|
||||
ret = ret*10 + (*buf[0] - '0');
|
||||
(*buf)++;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Converts the character string s to values which are stored in tm
|
||||
* using the format specified by format
|
||||
**/
|
||||
char *
|
||||
unbound_strptime(const char *s, const char *format, struct tm *tm)
|
||||
{
|
||||
int c, ret;
|
||||
int split_year = 0;
|
||||
|
||||
while ((c = *format) != '\0') {
|
||||
/* whitespace, literal or format */
|
||||
if (isspace((unsigned char)c)) { /* whitespace */
|
||||
/** whitespace matches zero or more whitespace characters in the
|
||||
* input string.
|
||||
**/
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
else if (c == '%') { /* format */
|
||||
format++;
|
||||
c = *format;
|
||||
switch (c) {
|
||||
case '%': /* %% is converted to % */
|
||||
if (*s != c) {
|
||||
return NULL;
|
||||
}
|
||||
s++;
|
||||
break;
|
||||
case 'a': /* weekday name, abbreviated or full */
|
||||
case 'A':
|
||||
ret = match_string(&s, full_weekdays);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_weekdays);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'b': /* month name, abbreviated or full */
|
||||
case 'B':
|
||||
case 'h':
|
||||
ret = match_string(&s, full_months);
|
||||
if (ret < 0)
|
||||
ret = match_string(&s, abb_months);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mon = ret;
|
||||
break;
|
||||
case 'c': /* date and time representation */
|
||||
if (!(s = unbound_strptime(s, "%x %X", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'C': /* century number */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (split_year) {
|
||||
tm->tm_year = ret*100 + (tm->tm_year%100);
|
||||
}
|
||||
else {
|
||||
tm->tm_year = ret*100 - TM_YEAR_BASE;
|
||||
split_year = 1;
|
||||
}
|
||||
break;
|
||||
case 'd': /* day of month */
|
||||
case 'e':
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 31) { /* must be in [01,31] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_mday = ret;
|
||||
break;
|
||||
case 'D': /* equivalent to %m/%d/%y */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'H': /* hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 23) { /* must be in [00,23] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'I': /* 12hr clock hour */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
if (ret == 12) /* actually [0,11] */
|
||||
ret = 0;
|
||||
tm->tm_hour = ret;
|
||||
break;
|
||||
case 'j': /* day of year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 366) { /* must be in [001,366] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_yday = ret;
|
||||
break;
|
||||
case 'm': /* month */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 1 || ret > 12) { /* must be in [01,12] */
|
||||
return NULL;
|
||||
}
|
||||
/* months go from 0-11 */
|
||||
tm->tm_mon = (ret-1);
|
||||
break;
|
||||
case 'M': /* minute */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 59) { /* must be in [00,59] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_min = ret;
|
||||
break;
|
||||
case 'n': /* arbitrary whitespace */
|
||||
case 't':
|
||||
while (isspace((unsigned char)*s))
|
||||
s++;
|
||||
break;
|
||||
case 'p': /* am pm */
|
||||
ret = match_string(&s, ampm);
|
||||
if (ret < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (tm->tm_hour < 0 || tm->tm_hour > 11) { /* %I */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ret == 1) /* pm */
|
||||
tm->tm_hour += 12;
|
||||
break;
|
||||
case 'r': /* equivalent of %I:%M:%S %p */
|
||||
if (!(s = unbound_strptime(s, "%I:%M:%S %p", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'R': /* equivalent of %H:%M */
|
||||
if (!(s = unbound_strptime(s, "%H:%M", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'S': /* seconds */
|
||||
ret = str2int(&s, 2);
|
||||
/* 60 may occur for leap seconds */
|
||||
/* earlier 61 was also allowed */
|
||||
if (ret < 0 || ret > 60) { /* must be in [00,60] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_sec = ret;
|
||||
break;
|
||||
case 'T': /* equivalent of %H:%M:%S */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'U': /* week number, with the first Sun of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'w': /* day of week */
|
||||
ret = str2int(&s, 1);
|
||||
if (ret < 0 || ret > 6) { /* must be in [0,6] */
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_wday = ret;
|
||||
break;
|
||||
case 'W': /* week number, with the first Mon of Jan being w1 */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 53) { /* must be in [00,53] */
|
||||
return NULL;
|
||||
}
|
||||
/** it is hard (and not necessary for nsd) to determine time
|
||||
* data from week number.
|
||||
**/
|
||||
break;
|
||||
case 'x': /* date format */
|
||||
if (!(s = unbound_strptime(s, "%m/%d/%y", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'X': /* time format */
|
||||
if (!(s = unbound_strptime(s, "%H:%M:%S", tm))) {
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case 'y': /* last two digits of a year */
|
||||
ret = str2int(&s, 2);
|
||||
if (ret < 0 || ret > 99) { /* must be in [00,99] */
|
||||
return NULL;
|
||||
}
|
||||
if (split_year) {
|
||||
tm->tm_year = ((tm->tm_year/100) * 100) + ret;
|
||||
}
|
||||
else {
|
||||
split_year = 1;
|
||||
|
||||
/** currently:
|
||||
* if in [0,68] we are in 21th century,
|
||||
* if in [69,99] we are in 20th century.
|
||||
**/
|
||||
if (ret < 69) /* 2000 */
|
||||
ret += 100;
|
||||
tm->tm_year = ret;
|
||||
}
|
||||
break;
|
||||
case 'Y': /* year */
|
||||
ret = str2int(&s, 4);
|
||||
if (ret < 0 || ret > 9999) {
|
||||
return NULL;
|
||||
}
|
||||
tm->tm_year = ret - TM_YEAR_BASE;
|
||||
break;
|
||||
case '\0':
|
||||
default: /* unsupported, cannot match format */
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else { /* literal */
|
||||
/* if input cannot match format, return NULL */
|
||||
if (*s != c)
|
||||
return NULL;
|
||||
s++;
|
||||
}
|
||||
|
||||
format++;
|
||||
}
|
||||
|
||||
/* return pointer to remainder of s */
|
||||
return (char*) s;
|
||||
}
|
||||
|
||||
#endif /* STRPTIME_WORKS */
|
||||
@@ -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
+299
-341
@@ -1,12 +1,14 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2013-06-10'
|
||||
timestamp='2007-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
@@ -15,23 +17,27 @@ timestamp='2013-06-10'
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
#
|
||||
# Originally written by Per Bothner.
|
||||
#
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
#
|
||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Originally written by Per Bothner <per@bothner.com>.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
# exits with 0. Otherwise, it exits with 1.
|
||||
#
|
||||
# The plan is that this can be called by configure scripts if you
|
||||
# don't specify an explicit build system type.
|
||||
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
usage="\
|
||||
@@ -50,7 +56,8 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -132,33 +139,12 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case "${UNAME_SYSTEM}" in
|
||||
Linux|GNU|GNU/*)
|
||||
# If the system lacks a compiler, then just pick glibc.
|
||||
# We could probably try harder.
|
||||
LIBC=gnu
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat <<-EOF > $dummy.c
|
||||
#include <features.h>
|
||||
#if defined(__UCLIBC__)
|
||||
LIBC=uclibc
|
||||
#elif defined(__dietlibc__)
|
||||
LIBC=dietlibc
|
||||
#else
|
||||
LIBC=gnu
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
|
||||
;;
|
||||
esac
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# NetBSD (nbsd) targets should (where applicable) match one or
|
||||
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
@@ -184,7 +170,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
|
||||
eval $set_cc_for_build
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ELF__
|
||||
| grep __ELF__ >/dev/null
|
||||
then
|
||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||
# Return netbsd for either. FIX?
|
||||
@@ -194,7 +180,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
os=netbsd
|
||||
os=netbsd
|
||||
;;
|
||||
esac
|
||||
# The OS release
|
||||
@@ -215,10 +201,6 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit ;;
|
||||
*:Bitrig:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:OpenBSD:*:*)
|
||||
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
|
||||
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
|
||||
@@ -241,7 +223,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
;;
|
||||
*5.*)
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
|
||||
;;
|
||||
esac
|
||||
# According to Compaq, /usr/sbin/psrinfo has been available on
|
||||
@@ -287,10 +269,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
|
||||
exitcode=$?
|
||||
trap '' 0
|
||||
exit $exitcode ;;
|
||||
exit ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||
@@ -316,12 +295,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
echo s390-ibm-zvmoe
|
||||
exit ;;
|
||||
*:OS400:*:*)
|
||||
echo powerpc-ibm-os400
|
||||
echo powerpc-ibm-os400
|
||||
exit ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
arm*:riscos:*:*|arm*:RISCOS:*:*)
|
||||
arm:riscos:*:*|arm:RISCOS:*:*)
|
||||
echo arm-unknown-riscos
|
||||
exit ;;
|
||||
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
|
||||
@@ -345,33 +324,14 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
case `/usr/bin/uname -p` in
|
||||
sparc) echo sparc-icl-nx7; exit ;;
|
||||
esac ;;
|
||||
s390x:SunOS:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
|
||||
echo i386-pc-auroraux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
|
||||
eval $set_cc_for_build
|
||||
SUN_ARCH="i386"
|
||||
# If there is a compiler, see if it is configured for 64-bit objects.
|
||||
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
|
||||
# This test works for both compilers.
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
SUN_ARCH="x86_64"
|
||||
fi
|
||||
fi
|
||||
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*)
|
||||
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit ;;
|
||||
sun4*:SunOS:6*:*)
|
||||
# According to config.sub, this is the proper way to canonicalize
|
||||
@@ -415,23 +375,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
exit ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit ;;
|
||||
m68k:machten:*:*)
|
||||
echo m68k-apple-machten${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -501,8 +461,8 @@ EOF
|
||||
echo m88k-motorola-sysv3
|
||||
exit ;;
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
@@ -515,7 +475,7 @@ EOF
|
||||
else
|
||||
echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
exit ;;
|
||||
@@ -572,7 +532,7 @@ EOF
|
||||
echo rs6000-ibm-aix3.2
|
||||
fi
|
||||
exit ;;
|
||||
*:AIX:*:[4567])
|
||||
*:AIX:*:[45])
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
@@ -615,52 +575,52 @@ EOF
|
||||
9000/[678][0-9][0-9])
|
||||
if [ -x /usr/bin/getconf ]; then
|
||||
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
|
||||
case "${sc_cpu_version}" in
|
||||
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
|
||||
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
|
||||
532) # CPU_PA_RISC2_0
|
||||
case "${sc_kernel_bits}" in
|
||||
32) HP_ARCH="hppa2.0n" ;;
|
||||
64) HP_ARCH="hppa2.0w" ;;
|
||||
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
|
||||
esac ;;
|
||||
esac
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
if [ "${HP_ARCH}" = "" ]; then
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
|
||||
test -z "$HP_ARCH" && HP_ARCH=hppa
|
||||
@@ -680,7 +640,7 @@ EOF
|
||||
# => hppa64-hp-hpux11.23
|
||||
|
||||
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
|
||||
grep -q __LP64__
|
||||
grep __LP64__ >/dev/null
|
||||
then
|
||||
HP_ARCH="hppa2.0w"
|
||||
else
|
||||
@@ -751,22 +711,22 @@ EOF
|
||||
exit ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
|
||||
if getsysinfo -f scalar_acc
|
||||
then echo c32-convex-bsd
|
||||
else echo c2-convex-bsd
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
|
||||
echo c34-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
|
||||
echo c38-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
|
||||
echo c4-convex-bsd
|
||||
exit ;;
|
||||
exit ;;
|
||||
CRAY*Y-MP:*:*:*)
|
||||
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit ;;
|
||||
@@ -790,14 +750,14 @@ EOF
|
||||
exit ;;
|
||||
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
|
||||
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
5000:UNIX_System_V:4.*:*)
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
|
||||
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit ;;
|
||||
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
@@ -809,51 +769,40 @@ EOF
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:FreeBSD:*:*)
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
case ${UNAME_PROCESSOR} in
|
||||
case ${UNAME_MACHINE} in
|
||||
pc98)
|
||||
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
amd64)
|
||||
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
*)
|
||||
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
|
||||
esac
|
||||
exit ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit ;;
|
||||
*:MINGW64*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw64
|
||||
exit ;;
|
||||
*:MINGW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit ;;
|
||||
i*:MSYS*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msys
|
||||
exit ;;
|
||||
i*:windows32*:*)
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
# uname -m includes "-pc" on this system.
|
||||
echo ${UNAME_MACHINE}-mingw32
|
||||
exit ;;
|
||||
i*:PW*:*)
|
||||
echo ${UNAME_MACHINE}-pc-pw32
|
||||
exit ;;
|
||||
*:Interix*:*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
*:Interix*:[3456]*)
|
||||
case ${UNAME_MACHINE} in
|
||||
x86)
|
||||
echo i586-pc-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
authenticamd | genuineintel | EM64T)
|
||||
EM64T | authenticamd)
|
||||
echo x86_64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
IA64)
|
||||
echo ia64-unknown-interix${UNAME_RELEASE}
|
||||
exit ;;
|
||||
esac ;;
|
||||
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
|
||||
echo i${UNAME_MACHINE}-pc-mks
|
||||
exit ;;
|
||||
8664:Windows_NT:*)
|
||||
echo x86_64-pc-mks
|
||||
exit ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
@@ -874,21 +823,93 @@ EOF
|
||||
exit ;;
|
||||
*:GNU:*:*)
|
||||
# the GNU system
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit ;;
|
||||
*:GNU/*:*:*)
|
||||
# other systems with GNU libc and userland
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
|
||||
exit ;;
|
||||
i*86:Minix:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-minix
|
||||
exit ;;
|
||||
aarch64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
arm*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
aarch64_be:Linux:*:*)
|
||||
UNAME_MACHINE=aarch64_be
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo cris-axis-linux-gnu
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo crisv32-axis-linux-gnu
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo frv-unknown-linux-gnu
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
mips:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips
|
||||
#undef mipsel
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mipsel
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef mips64
|
||||
#undef mips64el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=mips64el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=mips64
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^CPU/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
|
||||
;;
|
||||
or32:Linux:*:*)
|
||||
echo or32-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-gnu
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-gnu
|
||||
exit ;;
|
||||
alpha:Linux:*:*)
|
||||
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
|
||||
@@ -899,132 +920,106 @@ EOF
|
||||
EV6) UNAME_MACHINE=alphaev6 ;;
|
||||
EV67) UNAME_MACHINE=alphaev67 ;;
|
||||
EV68*) UNAME_MACHINE=alphaev68 ;;
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep -q ld.so.1
|
||||
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arc:Linux:*:* | arceb:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
arm*:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_EABI__
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
else
|
||||
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep -q __ARM_PCS_VFP
|
||||
then
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
|
||||
else
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
|
||||
fi
|
||||
fi
|
||||
exit ;;
|
||||
avr32*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
cris:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
crisv32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
|
||||
exit ;;
|
||||
frv:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
hexagon:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
|
||||
exit ;;
|
||||
ia64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m32r*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
m68*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
mips:Linux:*:* | mips64:Linux:*:*)
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#undef CPU
|
||||
#undef ${UNAME_MACHINE}
|
||||
#undef ${UNAME_MACHINE}el
|
||||
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
|
||||
CPU=${UNAME_MACHINE}el
|
||||
#else
|
||||
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
|
||||
CPU=${UNAME_MACHINE}
|
||||
#else
|
||||
CPU=
|
||||
#endif
|
||||
#endif
|
||||
EOF
|
||||
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
|
||||
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
|
||||
;;
|
||||
or1k:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
or32:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
padre:Linux:*:*)
|
||||
echo sparc-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-${LIBC}
|
||||
esac
|
||||
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
|
||||
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
|
||||
exit ;;
|
||||
parisc:Linux:*:* | hppa:Linux:*:*)
|
||||
# Look for CPU level
|
||||
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
|
||||
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
|
||||
*) echo hppa-unknown-linux-${LIBC} ;;
|
||||
PA7*) echo hppa1.1-unknown-linux-gnu ;;
|
||||
PA8*) echo hppa2.0-unknown-linux-gnu ;;
|
||||
*) echo hppa-unknown-linux-gnu ;;
|
||||
esac
|
||||
exit ;;
|
||||
ppc64:Linux:*:*)
|
||||
echo powerpc64-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppc:Linux:*:*)
|
||||
echo powerpc-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppc64le:Linux:*:*)
|
||||
echo powerpc64le-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
ppcle:Linux:*:*)
|
||||
echo powerpcle-unknown-linux-${LIBC}
|
||||
parisc64:Linux:*:* | hppa64:Linux:*:*)
|
||||
echo hppa64-unknown-linux-gnu
|
||||
exit ;;
|
||||
s390:Linux:*:* | s390x:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-ibm-linux
|
||||
exit ;;
|
||||
sh64*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sh*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
exit ;;
|
||||
tile*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu
|
||||
exit ;;
|
||||
vax:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
|
||||
echo ${UNAME_MACHINE}-dec-linux-gnu
|
||||
exit ;;
|
||||
x86_64:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
echo x86_64-unknown-linux-gnu
|
||||
exit ;;
|
||||
xtensa*:Linux:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
|
||||
xtensa:Linux:*:*)
|
||||
echo xtensa-unknown-linux-gnu
|
||||
exit ;;
|
||||
i*86:Linux:*:*)
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
# Set LC_ALL=C to ensure ld outputs messages in English.
|
||||
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
|
||||
| sed -ne '/supported targets:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
s/.*supported targets: *//
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_targets" in
|
||||
elf32-i386)
|
||||
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
|
||||
;;
|
||||
a.out-i386-linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit ;;
|
||||
coff-i386)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit ;;
|
||||
"")
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld) or
|
||||
# one that does not give us useful --help.
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
|
||||
exit ;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
eval $set_cc_for_build
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <features.h>
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
LIBC=gnu
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
# else
|
||||
LIBC=gnulibc1
|
||||
# endif
|
||||
#else
|
||||
#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
LIBC=gnu
|
||||
#else
|
||||
LIBC=gnuaout
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __dietlibc__
|
||||
LIBC=dietlibc
|
||||
#endif
|
||||
EOF
|
||||
eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
|
||||
/^LIBC/{
|
||||
s: ::g
|
||||
p
|
||||
}'`"
|
||||
test x"${LIBC}" != x && {
|
||||
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
|
||||
exit
|
||||
}
|
||||
test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
|
||||
;;
|
||||
i*86:DYNIX/ptx:4*:*)
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
|
||||
# earlier versions are messed up and put the nodename in both
|
||||
@@ -1032,11 +1027,11 @@ EOF
|
||||
echo i386-sequent-sysv4
|
||||
exit ;;
|
||||
i*86:UNIX_SV:4.2MP:2.*)
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# Unixware is an offshoot of SVR4, but it has its own version
|
||||
# number series starting with 2...
|
||||
# I am not positive that other SVR4 systems won't match this,
|
||||
# I just have to hope. -- rms.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
# Use sysv4.2uw... so that sysv4* matches it.
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit ;;
|
||||
i*86:OS/2:*:*)
|
||||
@@ -1053,7 +1048,7 @@ EOF
|
||||
i*86:syllable:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-syllable
|
||||
exit ;;
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
|
||||
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
i*86:*DOS:*:*)
|
||||
@@ -1068,7 +1063,7 @@ EOF
|
||||
fi
|
||||
exit ;;
|
||||
i*86:*:5:[678]*)
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
# UnixWare 7.x, OpenUNIX and OpenServer 6.
|
||||
case `/bin/uname -X | grep "^Machine"` in
|
||||
*486*) UNAME_MACHINE=i486 ;;
|
||||
*Pentium) UNAME_MACHINE=i586 ;;
|
||||
@@ -1096,13 +1091,10 @@ EOF
|
||||
exit ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i586.
|
||||
# Note: whatever this is, it MUST be the same as what config.sub
|
||||
# prints for the "djgpp" host, or else GDB configury will decide that
|
||||
# this is a cross-build.
|
||||
echo i586-pc-msdosdjgpp
|
||||
exit ;;
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
exit ;;
|
||||
Intel:Mach:3*:*)
|
||||
echo i386-pc-mach3
|
||||
exit ;;
|
||||
@@ -1137,18 +1129,8 @@ EOF
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
|
||||
OS_REL='.3'
|
||||
test -r /etc/.relid \
|
||||
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; }
|
||||
/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
|
||||
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
|
||||
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
|
||||
&& { echo i486-ncr-sysv4; exit; } ;;
|
||||
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
|
||||
echo m68k-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1161,7 +1143,7 @@ EOF
|
||||
rs6000:LynxOS:2.*:*)
|
||||
echo rs6000-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
|
||||
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
|
||||
echo powerpc-unknown-lynxos${UNAME_RELEASE}
|
||||
exit ;;
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
@@ -1181,10 +1163,10 @@ EOF
|
||||
echo ns32k-sni-sysv
|
||||
fi
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
|
||||
# says <Richard.M.Bartel@ccMail.Census.GOV>
|
||||
echo i586-unisys-sysv4
|
||||
exit ;;
|
||||
*:UNIX_System_V:4*:FTX*)
|
||||
# From Gerald Hewes <hewes@openmarket.com>.
|
||||
# How about differentiating between stratus architectures? -djm
|
||||
@@ -1210,11 +1192,11 @@ EOF
|
||||
exit ;;
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit ;;
|
||||
exit ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit ;;
|
||||
@@ -1224,12 +1206,6 @@ EOF
|
||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit ;;
|
||||
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
|
||||
echo i586-pc-haiku
|
||||
exit ;;
|
||||
x86_64:Haiku:*:*)
|
||||
echo x86_64-unknown-haiku
|
||||
exit ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
@@ -1256,21 +1232,9 @@ EOF
|
||||
exit ;;
|
||||
*:Darwin:*:*)
|
||||
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
|
||||
eval $set_cc_for_build
|
||||
if test "$UNAME_PROCESSOR" = unknown ; then
|
||||
UNAME_PROCESSOR=powerpc
|
||||
fi
|
||||
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
|
||||
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
|
||||
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
|
||||
grep IS_64BIT_ARCH >/dev/null
|
||||
then
|
||||
case $UNAME_PROCESSOR in
|
||||
i386) UNAME_PROCESSOR=x86_64 ;;
|
||||
powerpc) UNAME_PROCESSOR=powerpc64 ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
case $UNAME_PROCESSOR in
|
||||
unknown) UNAME_PROCESSOR=powerpc ;;
|
||||
esac
|
||||
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
@@ -1284,10 +1248,7 @@ EOF
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit ;;
|
||||
NEO-?:NONSTOP_KERNEL:*:*)
|
||||
echo neo-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSE-*:NONSTOP_KERNEL:*:*)
|
||||
NSE-?:NONSTOP_KERNEL:*:*)
|
||||
echo nse-tandem-nsk${UNAME_RELEASE}
|
||||
exit ;;
|
||||
NSR-?:NONSTOP_KERNEL:*:*)
|
||||
@@ -1332,13 +1293,13 @@ EOF
|
||||
echo pdp10-unknown-its
|
||||
exit ;;
|
||||
SEI:*:*:SEIUX)
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
echo mips-sei-seiux${UNAME_RELEASE}
|
||||
exit ;;
|
||||
*:DragonFly:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit ;;
|
||||
*:*VMS:*:*)
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
UNAME_MACHINE=`(uname -p) 2>/dev/null`
|
||||
case "${UNAME_MACHINE}" in
|
||||
A*) echo alpha-dec-vms ; exit ;;
|
||||
I*) echo ia64-dec-vms ; exit ;;
|
||||
@@ -1353,14 +1314,11 @@ EOF
|
||||
i*86:rdos:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-rdos
|
||||
exit ;;
|
||||
i*86:AROS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-aros
|
||||
exit ;;
|
||||
x86_64:VMkernel:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-esx
|
||||
exit ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
eval $set_cc_for_build
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
@@ -1378,11 +1336,11 @@ main ()
|
||||
#include <sys/param.h>
|
||||
printf ("m68k-sony-newsos%s\n",
|
||||
#ifdef NEWSOS4
|
||||
"4"
|
||||
"4"
|
||||
#else
|
||||
""
|
||||
""
|
||||
#endif
|
||||
); exit (0);
|
||||
); exit (0);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1516,9 +1474,9 @@ This script, last modified $timestamp, has failed to recognize
|
||||
the operating system you are using. It is advised that you
|
||||
download the most up to date version of the config scripts from
|
||||
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
|
||||
and
|
||||
http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
|
||||
|
||||
If the version you run ($0) is already up to date, please
|
||||
send the following data and any information you think might be
|
||||
|
||||
+88
-674
File diff suppressed because it is too large
Load Diff
Vendored
+105
-270
@@ -1,40 +1,44 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
|
||||
# Inc.
|
||||
|
||||
timestamp='2013-08-10'
|
||||
timestamp='2007-04-29'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
|
||||
# 02110-1301, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
|
||||
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
|
||||
# Please send patches to <config-patches@gnu.org>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
@@ -68,7 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2013 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -115,18 +120,12 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
kopensolaris*-gnu* | \
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
android-linux)
|
||||
os=-linux-android
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
@@ -149,13 +148,10 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||
-apple | -axis | -knuth | -cray)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-bluegene*)
|
||||
os=-cnk
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
@@ -170,10 +166,10 @@ case $os in
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -218,12 +214,6 @@ case $os in
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*178)
|
||||
os=-lynxos178
|
||||
;;
|
||||
-lynx*5)
|
||||
os=-lynxos5
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
@@ -248,34 +238,24 @@ case $basic_machine in
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| aarch64 | aarch64_be \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| bfin \
|
||||
| c4x | c8051 | clipper \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| epiphany \
|
||||
| fido | fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||
| maxq | mb | microblaze | mcore | mep \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64octeon | mips64octeonel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64r5900 | mips64r5900el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
@@ -286,45 +266,31 @@ case $basic_machine in
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipsr5900 | mipsr5900el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 | nios2eb | nios2el \
|
||||
| nios | nios2 \
|
||||
| ns16k | ns32k \
|
||||
| open8 \
|
||||
| or1k | or32 \
|
||||
| or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu \
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
c54x)
|
||||
basic_machine=tic54x-unknown
|
||||
;;
|
||||
c55x)
|
||||
basic_machine=tic55x-unknown
|
||||
;;
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@@ -334,21 +300,6 @@ case $basic_machine in
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
strongarm | thumb | xscale)
|
||||
basic_machine=arm-unknown
|
||||
;;
|
||||
xgate)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
xscaleeb)
|
||||
basic_machine=armeb-unknown
|
||||
;;
|
||||
|
||||
xscaleel)
|
||||
basic_machine=armel-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
@@ -363,37 +314,29 @@ case $basic_machine in
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| microblaze-* | microblazeel-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64octeon-* | mips64octeonel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64r5900-* | mips64r5900el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
@@ -404,41 +347,31 @@ case $basic_machine in
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipsr5900-* | mipsr5900el-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||
| nios-* | nios2-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| tahoe-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
| tron-* \
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| xstormy16-* | xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-* | z80-*)
|
||||
;;
|
||||
# Recognize the basic CPU types without company name, with glob match.
|
||||
xtensa*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -456,7 +389,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@@ -502,10 +435,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
aros)
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -514,35 +443,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
blackfin)
|
||||
basic_machine=bfin-unknown
|
||||
os=-linux
|
||||
;;
|
||||
blackfin-*)
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
bluegene*)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-cnk
|
||||
;;
|
||||
c54x-*)
|
||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c55x-*)
|
||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c6x-*)
|
||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -571,8 +475,8 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16 | cr16-*)
|
||||
basic_machine=cr16-unknown
|
||||
cr16c)
|
||||
basic_machine=cr16c-unknown
|
||||
os=-elf
|
||||
;;
|
||||
crds | unos)
|
||||
@@ -610,10 +514,6 @@ case $basic_machine in
|
||||
basic_machine=m88k-motorola
|
||||
os=-sysv3
|
||||
;;
|
||||
dicos)
|
||||
basic_machine=i686-pc
|
||||
os=-dicos
|
||||
;;
|
||||
djgpp)
|
||||
basic_machine=i586-pc
|
||||
os=-msdosdjgpp
|
||||
@@ -729,6 +629,7 @@ case $basic_machine in
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
@@ -767,14 +668,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
;;
|
||||
m68knommu-*)
|
||||
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
m88k-omron*)
|
||||
basic_machine=m88k-omron
|
||||
;;
|
||||
@@ -786,15 +679,8 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze*)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i686-pc
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
@@ -829,18 +715,10 @@ case $basic_machine in
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i686-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
nacl)
|
||||
basic_machine=le32-unknown
|
||||
os=-nacl
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
@@ -905,12 +783,6 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
neo-tandem)
|
||||
basic_machine=neo-tandem
|
||||
;;
|
||||
nse-tandem)
|
||||
basic_machine=nse-tandem
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -941,14 +813,6 @@ case $basic_machine in
|
||||
basic_machine=i860-intel
|
||||
os=-osf
|
||||
;;
|
||||
parisc)
|
||||
basic_machine=hppa-unknown
|
||||
os=-linux
|
||||
;;
|
||||
parisc-*)
|
||||
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
pbd)
|
||||
basic_machine=sparc-tti
|
||||
;;
|
||||
@@ -993,10 +857,9 @@ case $basic_machine in
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
@@ -1006,7 +869,7 @@ case $basic_machine in
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
@@ -1021,11 +884,7 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos | rdos64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rdos32)
|
||||
rdos)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
@@ -1094,9 +953,6 @@ case $basic_machine in
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
strongarm-* | thumb-*)
|
||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
@@ -1153,9 +1009,17 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-linux-gnu
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
@@ -1224,9 +1088,6 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
xscale-* | xscalee[bl]-*)
|
||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
@@ -1235,10 +1096,6 @@ case $basic_machine in
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
z80-*-coff)
|
||||
basic_machine=z80-unknown
|
||||
os=-sim
|
||||
;;
|
||||
none)
|
||||
basic_machine=none-none
|
||||
os=-none
|
||||
@@ -1277,7 +1134,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
|
||||
@@ -1324,12 +1181,9 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-auroraux)
|
||||
os=-auroraux
|
||||
;;
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
@@ -1350,23 +1204,21 @@ case $os in
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
@@ -1374,7 +1226,7 @@ case $os in
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1413,7 +1265,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@@ -1462,7 +1314,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@@ -1498,14 +1350,12 @@ case $os in
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1528,10 +1378,10 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@@ -1543,23 +1393,8 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c8051-*)
|
||||
os=-elf
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic55x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic6x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@@ -1579,11 +1414,14 @@ case $basic_machine in
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
@@ -1592,9 +1430,6 @@ case $basic_machine in
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
or1k-*)
|
||||
os=-elf
|
||||
;;
|
||||
or32-*)
|
||||
os=-coff
|
||||
;;
|
||||
@@ -1613,7 +1448,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
@@ -1718,7 +1553,7 @@ case $basic_machine in
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-cnk*|-aix*)
|
||||
-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*)
|
||||
|
||||
+845
-1269
File diff suppressed because it is too large
Load Diff
@@ -8,26 +8,4 @@ distribution but may be helpful.
|
||||
* update-anchor.sh: shell script that uses unbound-host to update a set
|
||||
of trust anchor files. Run from cron twice a month.
|
||||
* unbound_munin_ : plugin for munin statistics report
|
||||
* unbound_cacti.tar.gz : setup files for cacti statistics report
|
||||
* selinux: the .fc and .te files for SElinux protection of the unbound daemon
|
||||
* unbound.plist: launchd configuration file for MacOSX.
|
||||
* build-unbound-localzone-from-hosts.pl: perl script to turn /etc/hosts into
|
||||
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.
|
||||
* 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_smf22.tar.gz: Solaris SMF installation/removal scripts.
|
||||
Contributed by Yuri Voinov.
|
||||
* unbound.socket and unbound.service: systemd files for unbound, install them
|
||||
in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
|
||||
|
||||
@@ -1,413 +0,0 @@
|
||||
Index: trunk/doc/unbound.conf.5.in
|
||||
===================================================================
|
||||
--- trunk/doc/unbound.conf.5.in (revision 3587)
|
||||
+++ trunk/doc/unbound.conf.5.in (working copy)
|
||||
@@ -593,6 +593,13 @@
|
||||
possible. Best effort approach, full QNAME and original QTYPE will be sent when
|
||||
upstream replies with a RCODE other than NOERROR. Default is off.
|
||||
.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 private\-address: \fI<IP address or subnet>
|
||||
Give IPv4 of IPv6 addresses or classless subnets. These are addresses
|
||||
on your private network, and are not allowed to be returned for
|
||||
Index: trunk/iterator/iter_scrub.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_scrub.c (revision 3587)
|
||||
+++ trunk/iterator/iter_scrub.c (working copy)
|
||||
@@ -617,6 +617,32 @@
|
||||
}
|
||||
|
||||
/**
|
||||
+ * ASN: Lookup A records from rrset cache.
|
||||
+ * @param qinfo: the question originally asked.
|
||||
+ * @param env: module environment with config and cache.
|
||||
+ * @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
|
||||
* the response to be in a "normalized" state -- that is, all "irrelevant"
|
||||
@@ -635,6 +661,7 @@
|
||||
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
|
||||
struct iter_env* ie)
|
||||
{
|
||||
+ 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;
|
||||
@@ -670,6 +697,13 @@
|
||||
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
|
||||
@@ -681,6 +715,24 @@
|
||||
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)) {
|
||||
Index: trunk/iterator/iter_utils.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iter_utils.c (revision 3587)
|
||||
+++ trunk/iterator/iter_utils.c (working copy)
|
||||
@@ -175,6 +175,7 @@
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
iter_env->supports_ipv4 = cfg->do_ip4;
|
||||
+ iter_env->aaaa_filter = cfg->aaaa_filter;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Index: trunk/iterator/iterator.c
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.c (revision 3587)
|
||||
+++ trunk/iterator/iterator.c (working copy)
|
||||
@@ -1776,6 +1776,53 @@
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * ASN: This event state was added as an intermediary step between
|
||||
+ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the
|
||||
+ * purpose of caching A records for the queried name.
|
||||
+ *
|
||||
+ * @param qstate: query state.
|
||||
+ * @param iq: iterator query state.
|
||||
+ * @param ie: iterator shared global environment.
|
||||
+ * @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)) {
|
||||
+ 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
|
||||
@@ -1823,6 +1870,13 @@
|
||||
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) {
|
||||
@@ -2922,6 +2976,61 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * ASN: Do final processing on responses to A queries originated from AAAA
|
||||
+ * queries. Events reach this state after the iterative resolution algorithm
|
||||
+ * terminates.
|
||||
+ * 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 interestes super querystates.
|
||||
*
|
||||
@@ -2941,6 +3050,9 @@
|
||||
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)
|
||||
@@ -2978,6 +3090,9 @@
|
||||
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;
|
||||
@@ -3270,6 +3385,8 @@
|
||||
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 :
|
||||
@@ -3294,6 +3411,7 @@
|
||||
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;
|
||||
Index: trunk/iterator/iterator.h
|
||||
===================================================================
|
||||
--- trunk/iterator/iterator.h (revision 3587)
|
||||
+++ trunk/iterator/iterator.h (working copy)
|
||||
@@ -113,6 +113,9 @@
|
||||
*/
|
||||
int* target_fetch_policy;
|
||||
|
||||
+ /** ASN: AAAA-filter flag */
|
||||
+ int aaaa_filter;
|
||||
+
|
||||
/** ip6.arpa dname in wireformat, used for qname-minimisation */
|
||||
uint8_t* ip6arpa_dname;
|
||||
};
|
||||
@@ -163,6 +166,14 @@
|
||||
INIT_REQUEST_3_STATE,
|
||||
|
||||
/**
|
||||
+ * This state is responsible for intercepting AAAA queries,
|
||||
+ * and launch a A subquery on the same target, to populate the
|
||||
+ * cache with A records, so the AAAA filter scrubbing logic can
|
||||
+ * 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.
|
||||
* This state is reponsible for iterating through a list of
|
||||
@@ -346,6 +357,13 @@
|
||||
*/
|
||||
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;
|
||||
|
||||
Index: trunk/pythonmod/interface.i
|
||||
===================================================================
|
||||
--- trunk/pythonmod/interface.i (revision 3587)
|
||||
+++ trunk/pythonmod/interface.i (working copy)
|
||||
@@ -632,6 +632,7 @@
|
||||
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;
|
||||
Index: trunk/util/config_file.c
|
||||
===================================================================
|
||||
--- trunk/util/config_file.c (revision 3587)
|
||||
+++ trunk/util/config_file.c (working copy)
|
||||
@@ -176,6 +176,7 @@
|
||||
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;
|
||||
Index: trunk/util/config_file.h
|
||||
===================================================================
|
||||
--- trunk/util/config_file.h (revision 3587)
|
||||
+++ trunk/util/config_file.h (working copy)
|
||||
@@ -179,6 +179,8 @@
|
||||
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 */
|
||||
Index: trunk/util/configlexer.lex
|
||||
===================================================================
|
||||
--- trunk/util/configlexer.lex (revision 3587)
|
||||
+++ trunk/util/configlexer.lex (working copy)
|
||||
@@ -267,6 +267,7 @@
|
||||
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
|
||||
caps-whitelist{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) }
|
||||
Index: trunk/util/configparser.y
|
||||
===================================================================
|
||||
--- trunk/util/configparser.y (revision 3587)
|
||||
+++ trunk/util/configparser.y (working copy)
|
||||
@@ -92,6 +92,7 @@
|
||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
||||
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
|
||||
+%token VAR_AAAA_FILTER
|
||||
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
|
||||
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
|
||||
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
|
||||
@@ -169,6 +170,7 @@
|
||||
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
||||
server_harden_referral_path | server_private_address |
|
||||
server_private_domain | server_extended_statistics |
|
||||
+ server_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 |
|
||||
@@ -893,6 +895,15 @@
|
||||
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,67 +0,0 @@
|
||||
#!/usr/bin/perl -WT
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $hostsfile = '/etc/hosts';
|
||||
my $localzonefile = '/etc/unbound/localzone.conf.new';
|
||||
|
||||
my $localzone = 'example.com';
|
||||
|
||||
open( HOSTS,"<${hostsfile}" ) or die( "Could not open ${hostsfile}: $!" );
|
||||
open( ZONE,">${localzonefile}" ) or die( "Could not open ${localzonefile}: $!" );
|
||||
|
||||
print ZONE "server:\n\n";
|
||||
print ZONE "local-zone: \"${localzone}\" transparent\n\n";
|
||||
|
||||
my %ptrhash;
|
||||
|
||||
while ( my $hostline = <HOSTS> ) {
|
||||
|
||||
# Skip comments
|
||||
if ( $hostline !~ "^#" and $hostline !~ '^\s+$' ) {
|
||||
|
||||
my @entries = split( /\s+/, $hostline );
|
||||
|
||||
my $ip;
|
||||
|
||||
my $count = 0;
|
||||
foreach my $entry ( @entries ) {
|
||||
if ( $count == 0 ) {
|
||||
$ip = $entry;
|
||||
} else {
|
||||
|
||||
if ( $count == 1) {
|
||||
|
||||
# Only return localhost for 127.0.0.1 and ::1
|
||||
if ( ($ip ne '127.0.0.1' and $ip ne '::1') or $entry =~ 'localhost' ) {
|
||||
if ( ! defined $ptrhash{$ip} ) {
|
||||
$ptrhash{$ip} = $entry;
|
||||
print ZONE "local-data-ptr: \"$ip $entry\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Use AAAA for IPv6 addresses
|
||||
my $a = 'A';
|
||||
if ( $ip =~ ':' ) {
|
||||
$a = 'AAAA';
|
||||
}
|
||||
|
||||
print ZONE "local-data: \"$entry ${a} $ip\"\n";
|
||||
|
||||
}
|
||||
$count++;
|
||||
}
|
||||
print ZONE "\n";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
__END__
|
||||
|
||||
@@ -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,39 +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="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
|
||||
|
||||
# OS commands
|
||||
CAT=`which cat`
|
||||
ECHO=`which echo`
|
||||
WGET=`which wget`
|
||||
|
||||
# Check Wget installed
|
||||
if [ ! -f $WGET ]; then
|
||||
echo "Wget not found. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
$WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \
|
||||
$CAT $work_dir/yoyo_ad_servers | \
|
||||
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,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: libcrypto libssl @PC_LIBEVENT_DEPENDENCY@ @PC_PY_DEPENDENCY@
|
||||
Libs: -L${libdir} -lunbound
|
||||
Libs.private: @SSLLIB@ @LIBS@
|
||||
Cflags: -I${includedir}
|
||||
@@ -1,22 +0,0 @@
|
||||
Index: validator/val_secalgo.c
|
||||
===================================================================
|
||||
--- validator/val_secalgo.c (revision 2759)
|
||||
+++ validator/val_secalgo.c (working copy)
|
||||
@@ -153,7 +153,7 @@
|
||||
switch(id) {
|
||||
case LDNS_RSAMD5:
|
||||
/* RFC 6725 deprecates RSAMD5 */
|
||||
- return 0;
|
||||
+ return 1;
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
case LDNS_RSASHA1:
|
||||
@@ -617,7 +617,7 @@
|
||||
switch(id) {
|
||||
case LDNS_RSAMD5:
|
||||
/* RFC 6725 deprecates RSAMD5 */
|
||||
- return 0;
|
||||
+ return 1;
|
||||
case LDNS_DSA:
|
||||
case LDNS_DSA_NSEC3:
|
||||
case LDNS_RSASHA1:
|
||||
@@ -1,134 +0,0 @@
|
||||
Index: smallapp/unbound-host.c
|
||||
===================================================================
|
||||
--- smallapp/unbound-host.c (revision 2115)
|
||||
+++ smallapp/unbound-host.c (working copy)
|
||||
@@ -62,9 +62,18 @@
|
||||
#include "libunbound/unbound.h"
|
||||
#include <ldns/ldns.h>
|
||||
|
||||
+/** status variable ala nagios */
|
||||
+#define FINAL_STATUS_OK 0
|
||||
+#define FINAL_STATUS_WARNING 1
|
||||
+#define FINAL_STATUS_CRITICAL 2
|
||||
+#define FINAL_STATUS_UNKNOWN 3
|
||||
+
|
||||
/** verbosity for unbound-host app */
|
||||
static int verb = 0;
|
||||
|
||||
+/** variable to determine final output */
|
||||
+static int final_status = FINAL_STATUS_UNKNOWN;
|
||||
+
|
||||
/** Give unbound-host usage, and exit (1). */
|
||||
static void
|
||||
usage()
|
||||
@@ -93,7 +102,7 @@
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
|
||||
/** determine if str is ip4 and put into reverse lookup format */
|
||||
@@ -138,7 +147,7 @@
|
||||
*res = strdup(buf);
|
||||
if(!*res) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -158,7 +167,7 @@
|
||||
}
|
||||
if(!res) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -172,7 +181,7 @@
|
||||
if(r == 0 && strcasecmp(t, "TYPE0") != 0 &&
|
||||
strcmp(t, "") != 0) {
|
||||
fprintf(stderr, "error unknown type %s\n", t);
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -191,7 +200,7 @@
|
||||
if(r == 0 && strcasecmp(c, "CLASS0") != 0 &&
|
||||
strcmp(c, "") != 0) {
|
||||
fprintf(stderr, "error unknown class %s\n", c);
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -207,6 +216,19 @@
|
||||
return "(insecure)";
|
||||
}
|
||||
|
||||
+/** update the final status for the exit code */
|
||||
+void
|
||||
+update_final_status(struct ub_result* result)
|
||||
+{
|
||||
+ if (final_status == FINAL_STATUS_UNKNOWN || final_status == FINAL_STATUS_OK) {
|
||||
+ if (result->secure) final_status = FINAL_STATUS_OK;
|
||||
+ else if (result->bogus) final_status = FINAL_STATUS_CRITICAL;
|
||||
+ else final_status = FINAL_STATUS_WARNING;
|
||||
+ }
|
||||
+ else if (final_status == FINAL_STATUS_WARNING && result->bogus)
|
||||
+ final_status = FINAL_STATUS_CRITICAL;
|
||||
+}
|
||||
+
|
||||
/** nice string for type */
|
||||
static void
|
||||
pretty_type(char* s, size_t len, int t)
|
||||
@@ -353,7 +375,7 @@
|
||||
} else {
|
||||
fprintf(stderr, "could not parse "
|
||||
"reply packet to ANY query\n");
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
ldns_pkt_free(p);
|
||||
|
||||
@@ -388,9 +410,10 @@
|
||||
ret = ub_resolve(ctx, q, t, c, &result);
|
||||
if(ret != 0) {
|
||||
fprintf(stderr, "resolve error: %s\n", ub_strerror(ret));
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
pretty_output(q, t, c, result, docname);
|
||||
+ update_final_status(result);
|
||||
ret = result->nxdomain;
|
||||
ub_resolve_free(result);
|
||||
return ret;
|
||||
@@ -427,7 +450,7 @@
|
||||
{
|
||||
if(r != 0) {
|
||||
fprintf(stderr, "error: %s\n", ub_strerror(r));
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -448,7 +471,7 @@
|
||||
ctx = ub_ctx_create();
|
||||
if(!ctx) {
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
- exit(1);
|
||||
+ exit(FINAL_STATUS_UNKNOWN);
|
||||
}
|
||||
|
||||
/* parse the options */
|
||||
@@ -509,5 +532,5 @@
|
||||
usage();
|
||||
|
||||
lookup(ctx, argv[0], qtype, qclass);
|
||||
- return 0;
|
||||
+ return final_status;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd >
|
||||
<plist version="1.0">
|
||||
<!--
|
||||
Unbound plist file for use by MacOSX launchd(8) using launchctl(1).
|
||||
Copy this file to /Library/LaunchDaemons. Launchd keeps unbound running.
|
||||
|
||||
Setup your unbound.conf with the following additional settings.
|
||||
server:
|
||||
do-daemonize: no
|
||||
username: ""
|
||||
chroot: ""
|
||||
directory: ""
|
||||
These actions are performed by launchd (for the option values, see below).
|
||||
|
||||
-->
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>unbound</string>
|
||||
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>unbound</string>
|
||||
</array>
|
||||
|
||||
<key>UserName</key>
|
||||
<string>unbound</string>
|
||||
|
||||
<key>RootDirectory</key>
|
||||
<string>/usr/local/etc/unbound</string>
|
||||
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/usr/local/etc/unbound</string>
|
||||
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,28 +0,0 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecReload=/bin/kill -HUP $MAINPID
|
||||
ExecStart=/home/vagrant/unbound_systemd/unbound
|
||||
NotifyAccess=main
|
||||
Type=notify
|
||||
CapabilityBoundingSet=CAP_IPC_LOCK CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT
|
||||
MemoryDenyWriteExecute=true
|
||||
NoNewPrivileges=true
|
||||
PrivateDevices=true
|
||||
PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectControlGroups=true
|
||||
ProtectKernelModules=true
|
||||
ProtectKernelTunables=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/etc/unbound /run
|
||||
RestrictAddressFamilies=AF_INET AF_UNIX
|
||||
RestrictRealtime=true
|
||||
SystemCallArchitectures=native
|
||||
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
|
||||
|
||||
@@ -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
|
||||
+6
-15
@@ -1,15 +1,14 @@
|
||||
Summary: Validating, recursive, and caching DNS resolver
|
||||
Name: unbound
|
||||
Version: 1.4.18
|
||||
Version: 1.0.1
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
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, ldns-devel
|
||||
BuildRequires: flex, openssl-devel
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS resolver.
|
||||
@@ -29,6 +28,10 @@ The source code is under a BSD License.
|
||||
|
||||
# configure with /var/unbound/unbound.conf so that all default chroot,
|
||||
# pidfile and config file are in /var/unbound, ready for chroot jail set up.
|
||||
#
|
||||
# This is a build using libldns builtin version, the resulting binaries
|
||||
# do not require libldns and this package does not have version dependencies.
|
||||
# Could be smaller using a dependency on libldns (use --with-ldns=).
|
||||
%configure --with-conf-file=%{_localstatedir}/%{name}/unbound.conf --disable-rpath
|
||||
|
||||
%build
|
||||
@@ -89,18 +92,6 @@ if [ "$1" -ge "1" ]; then
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* 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
|
||||
- removed --disable-gost, assume recent openssl on the destination platform.
|
||||
|
||||
* Wed Mar 16 2011 Harold Jones <hajones@verisign.com> - 1.4.8
|
||||
- Bump version number to latest
|
||||
- Add expat-devel to BuildRequires
|
||||
- Added --disable-gost for building on CentOS 5.x
|
||||
- Added --with-ldns-builtin for CentOS 5.x
|
||||
|
||||
* Thu May 22 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 1.0.0
|
||||
- contrib changes from Patrick Vande Walle.
|
||||
|
||||
|
||||
+47
-295
@@ -1,44 +1,23 @@
|
||||
# not ready yet
|
||||
%{?!with_python: %global with_python 1}
|
||||
|
||||
%if %{with_python}
|
||||
%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
|
||||
%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
|
||||
%endif
|
||||
|
||||
Summary: Validating, recursive, and caching DNS(SEC) resolver
|
||||
Name: unbound
|
||||
Version: 1.4.13
|
||||
Version: 1.1.0
|
||||
Release: 1%{?dist}
|
||||
License: BSD
|
||||
Url: http://www.nlnetlabs.nl/unbound/
|
||||
Source: http://www.unbound.net/downloads/%{name}-%{version}.tar.gz
|
||||
Source1: unbound.init
|
||||
Source2: unbound.conf
|
||||
Source3: unbound.munin
|
||||
Source4: unbound_munin_
|
||||
Source5: root.key
|
||||
Patch1: unbound-1.2-glob.patch
|
||||
|
||||
Group: System Environment/Daemons
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: flex, openssl-devel , ldns-devel >= 1.5.0,
|
||||
BuildRequires: libevent-devel expat-devel
|
||||
%if %{with_python}
|
||||
BuildRequires: python-devel swig
|
||||
%endif
|
||||
# Required for SVN versions
|
||||
# BuildRequires: bison
|
||||
|
||||
BuildRequires: flex, openssl-devel, ldns-devel >= 1.3.0, libevent-devel
|
||||
Requires(post): chkconfig
|
||||
Requires(preun): chkconfig
|
||||
Requires(preun): initscripts
|
||||
Requires(postun): initscripts
|
||||
Requires: ldns >= 1.5.0
|
||||
Requires: ldns >= 1.3.0
|
||||
Requires(pre): shadow-utils
|
||||
|
||||
Obsoletes: dnssec-conf < 1.27-2
|
||||
Provides: dnssec-conf = 1.27-1
|
||||
# Is this obsolete?
|
||||
#Provides: caching-nameserver
|
||||
|
||||
%description
|
||||
Unbound is a validating, recursive, and caching DNS(SEC) resolver.
|
||||
@@ -51,19 +30,11 @@ Unbound is designed as a set of modular components, so that also
|
||||
DNSSEC (secure DNS) validation and stub-resolvers (that do not run
|
||||
as a server, but are linked into an application) are easily possible.
|
||||
|
||||
%package munin
|
||||
Summary: Plugin for the munin / munin-node monitoring package
|
||||
Group: System Environment/Daemons
|
||||
Requires: munin-node
|
||||
Requires: %{name} = %{version}-%{release}, bc
|
||||
|
||||
%description munin
|
||||
Plugin for the munin / munin-node monitoring package
|
||||
|
||||
%package devel
|
||||
Summary: Development package that includes the unbound header files
|
||||
Group: Development/Libraries
|
||||
Requires: %{name}-libs = %{version}-%{release}, openssl-devel, ldns-devel
|
||||
Requires: libevent-devel
|
||||
|
||||
%description devel
|
||||
The devel package contains the unbound library and the include files
|
||||
@@ -73,60 +44,46 @@ Summary: Libraries used by the unbound server and client applications
|
||||
Group: Applications/System
|
||||
Requires(post): /sbin/ldconfig
|
||||
Requires(postun): /sbin/ldconfig
|
||||
Requires: openssl
|
||||
|
||||
%description libs
|
||||
Contains libraries used by the unbound server and client applications
|
||||
|
||||
%if %{with_python}
|
||||
%package python
|
||||
Summary: Python modules and extensions for unbound
|
||||
Group: Applications/System
|
||||
Requires: %{name}-libs = %{version}-%{release}
|
||||
|
||||
%description python
|
||||
Python modules and extensions for unbound
|
||||
%endif
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1
|
||||
|
||||
%build
|
||||
%configure --with-ldns= --with-libevent --with-pthreads --with-ssl \
|
||||
--disable-rpath --disable-static \
|
||||
--with-conf-file=%{_sysconfdir}/%{name}/unbound.conf \
|
||||
--with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid \
|
||||
%if %{with_python}
|
||||
--with-pythonmodule --with-pyunbound \
|
||||
%endif
|
||||
--enable-sha2 --disable-gost
|
||||
%{__make} %{?_smp_mflags}
|
||||
--disable-rpath --enable-debug --disable-static \
|
||||
--with-run-dir=%{_localstatedir}/lib/%{name}\
|
||||
--with-conf-file=%{_localstatedir}/lib/%{name}/unbound.conf \
|
||||
--with-pidfile=%{_localstatedir}/run/%{name}/%{name}.pid
|
||||
%{__make} CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE" QUIET=no %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
%{__make} DESTDIR=%{buildroot} install
|
||||
install -d 0755 %{buildroot}%{_localstatedir}/lib/%{name}
|
||||
install -d 0755 %{buildroot}%{_initrddir}
|
||||
#install -m 0755 contrib/unbound.init %{buildroot}%{_initrddir}/unbound
|
||||
install -m 0755 %{SOURCE1} %{buildroot}%{_initrddir}/unbound
|
||||
install -m 0755 %{SOURCE2} %{buildroot}%{_sysconfdir}/unbound
|
||||
# Install munin plugin and its softlinks
|
||||
install -d 0755 %{buildroot}%{_sysconfdir}/munin/plugin-conf.d
|
||||
install -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/munin/plugin-conf.d/unbound
|
||||
install -d 0755 %{buildroot}%{_datadir}/munin/plugins/
|
||||
install -m 0755 %{SOURCE4} %{buildroot}%{_datadir}/munin/plugins/unbound
|
||||
for plugin in unbound_munin_hits unbound_munin_queue unbound_munin_memory unbound_munin_by_type unbound_munin_by_class unbound_munin_by_opcode unbound_munin_by_rcode unbound_munin_by_flags unbound_munin_histogram; do
|
||||
ln -s unbound %{buildroot}%{_datadir}/munin/plugins/$plugin
|
||||
done
|
||||
#overwrite stock unbound.conf with our own
|
||||
install -m 0755 %{SOURCE2} %{buildroot}%{_localstatedir}/lib/%{name}
|
||||
|
||||
# install root and DLV key
|
||||
install -m 0644 %{SOURCE5} %{SOURCE6} %{buildroot}%{_sysconfdir}/unbound/
|
||||
# add symbolic link from /etc/unbound.conf -> /var/unbound/unbound.conf
|
||||
|
||||
( cd %{buildroot}%{_sysconfdir}/ ; ln -s ..%{_localstatedir}/lib/unbound/unbound.conf )
|
||||
# remove static library from install (fedora packaging guidelines)
|
||||
rm %{buildroot}%{_libdir}/*.la
|
||||
%if %{with_python}
|
||||
rm %{buildroot}%{python_sitearch}/*.la
|
||||
%endif
|
||||
rm -rf %{buildroot}%{_libdir}/*.la
|
||||
|
||||
# The chroot needs /dev/log, /dev/random, /etc/resolv.conf and /etc/localtime
|
||||
# but the init script uses mount --bind, so just create empty files
|
||||
mkdir -p %{buildroot}%{_localstatedir}/lib/unbound/etc \
|
||||
%{buildroot}%{_localstatedir}/lib/unbound/dev
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/etc/resolv.conf
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/etc/localtime
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/dev/log
|
||||
echo "Used for mount --bind in initscript" > %{buildroot}%{_localstatedir}/lib/unbound/dev/random
|
||||
mkdir -p %{buildroot}%{_localstatedir}/lib/unbound/var/run/unbound
|
||||
mkdir -p %{buildroot}%{_localstatedir}/run/unbound
|
||||
|
||||
%clean
|
||||
@@ -136,26 +93,21 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%defattr(-,root,root,-)
|
||||
%doc doc/README doc/CREDITS doc/LICENSE doc/FEATURES
|
||||
%attr(0755,root,root) %{_initrddir}/%{name}
|
||||
%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}/root.key
|
||||
# the chroot env
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}
|
||||
%attr(0755,unbound,unbound) %dir %{_localstatedir}/run/%{name}
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/dev
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/etc
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var/run
|
||||
%attr(0755,root,root) %dir %{_localstatedir}/lib/%{name}/var/run/unbound
|
||||
%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/unbound.conf
|
||||
%attr(0644,root,root) %config(noreplace) %{_localstatedir}/lib/%{name}/unbound.conf
|
||||
%attr(0644,root,root) %{_localstatedir}/lib/%{name}/dev/*
|
||||
%attr(0644,root,root) %{_localstatedir}/lib/%{name}/etc/*
|
||||
%{_sbindir}/*
|
||||
%{_mandir}/*/*
|
||||
|
||||
%if %{with_python}
|
||||
%files python
|
||||
%defattr(-,root,root,-)
|
||||
%{python_sitearch}/*
|
||||
%doc libunbound/python/examples/*
|
||||
%doc pythonmod/examples/*
|
||||
%endif
|
||||
|
||||
%files munin
|
||||
%defattr(-,root,root,-)
|
||||
%config(noreplace) %{_sysconfdir}/munin/plugin-conf.d/unbound
|
||||
%{_datadir}/munin/plugins/unbound*
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
%{_libdir}/libunbound.so
|
||||
@@ -170,17 +122,18 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%pre
|
||||
getent group unbound >/dev/null || groupadd -r unbound
|
||||
getent passwd unbound >/dev/null || \
|
||||
useradd -r -g unbound -d %{_sysconfdir}/unbound -s /sbin/nologin \
|
||||
useradd -r -g unbound -d %{_localstatedir}/lib/%{name} -s /sbin/nologin \
|
||||
-c "Unbound DNS resolver" unbound
|
||||
exit 0
|
||||
|
||||
%post
|
||||
%post
|
||||
/sbin/chkconfig --add %{name}
|
||||
|
||||
%post libs -p /sbin/ldconfig
|
||||
|
||||
|
||||
%preun
|
||||
if [ "$1" -eq 0 ]; then
|
||||
if [ $1 -eq 0 ]; then
|
||||
/sbin/service %{name} stop >/dev/null 2>&1
|
||||
/sbin/chkconfig --del %{name}
|
||||
fi
|
||||
@@ -193,210 +146,6 @@ fi
|
||||
%postun libs -p /sbin/ldconfig
|
||||
|
||||
%changelog
|
||||
* Tue Sep 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.13-1
|
||||
- Updated to 1.4.13
|
||||
- Fix install location of pythonmod from sitelib to sitearch
|
||||
- Removed patches merged in by upstream
|
||||
- Removed versioned openssl dep, it differs per branch
|
||||
|
||||
* Mon Aug 08 2011 Paul Wouters <paul@xelerance.com> - 1.4.12-3
|
||||
- Added pythonmod docs and examples
|
||||
- Fix for python module load in the server (Tom Hendrikx)
|
||||
- No longer enable --enable-debug as it causes degraded performance
|
||||
under load.
|
||||
|
||||
* Mon Jul 18 2011 Paul Wouters <paul@xelerance.com> - 1.4.12-1
|
||||
- Updated to 1.4.12
|
||||
|
||||
* Sun Jul 03 2011 Paul Wouters <paul@xelerance.com> - 1.4.11-1
|
||||
- Updated to 1.4.11
|
||||
- removed integrated CVE patch
|
||||
- updated stock unbound.conf for new options introduced
|
||||
|
||||
* Mon Jun 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.10-1
|
||||
- Added ghost for /var/run/unbound (bz#656710)
|
||||
|
||||
* Mon Jun 06 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-3
|
||||
- rebuilt
|
||||
|
||||
* Wed May 25 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-2
|
||||
- Applied patch for CVE-2011-1922 DoS vulnerability
|
||||
|
||||
* Sun Mar 27 2011 Paul Wouters <paul@xelerance.com> - 1.4.9-1
|
||||
- Updated to 1.4.9
|
||||
|
||||
* Sat Feb 12 2011 Paul Wouters <paul@xelerance.com> - 1.4.8-2
|
||||
- rebuilt
|
||||
|
||||
* Tue Jan 25 2011 Paul Wouters <paul@xelerance.com> - 1.4.8-1
|
||||
- Updated to 1.4.8
|
||||
- Enable root key for DNSSEC
|
||||
- Fix unbound-munin to use proper file (could cause excessive logging)
|
||||
- Build unbound-python per default
|
||||
- Disable gost as Fedora/EPEL does not allow ECC and has mangled openssl
|
||||
|
||||
* Tue Oct 26 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-4
|
||||
- Revert last build - it was on the wrong branch
|
||||
|
||||
* Tue Oct 26 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-3
|
||||
- Disable do-ipv6 per default - causes severe degradation on non-ipv6 machines
|
||||
(see comments in inbound.conf)
|
||||
|
||||
* Tue Jun 15 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-2
|
||||
- Bump release - forgot to upload the new tar ball.
|
||||
|
||||
* Tue Jun 15 2010 Paul Wouters <paul@xelerance.com> - 1.4.5-1
|
||||
- Upgraded to 1.4.5
|
||||
|
||||
* Mon May 31 2010 Paul Wouters <paul@xelerance.com> - 1.4.4-2
|
||||
- Added accidentally omitted svn patches to cvs
|
||||
|
||||
* Mon May 31 2010 Paul Wouters <paul@xelerance.com> - 1.4.4-1
|
||||
- Upgraded to 1.4.4 with svn patches
|
||||
- Obsolete dnssec-conf to ensure it is de-installed
|
||||
|
||||
* Thu Mar 11 2010 Paul Wouters <paul@xelerance.com> - 1.4.3-1
|
||||
- Update to 1.4.3 that fixes 64bit crasher
|
||||
|
||||
* Tue Mar 09 2010 Paul Wouters <paul@xelerance.com> - 1.4.2-1
|
||||
- Updated to 1.4.2
|
||||
- Updated unbound.conf with new options
|
||||
- Enabled pre-fetching DNSKEY records (DNSSEC speedup)
|
||||
- Enabled re-fetching popular records before they expire
|
||||
- Enabled logging of DNSSEC validation errors
|
||||
|
||||
* Mon Mar 01 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-5
|
||||
- Overriding -D_GNU_SOURCE is no longer needed. This fixes DSO issues
|
||||
with pthreads
|
||||
|
||||
* Wed Feb 24 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-3
|
||||
- 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
|
||||
- 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]
|
||||
|
||||
* Tue Jan 05 2010 Paul Wouters <paul@xelerance.com> - 1.4.1-1
|
||||
- Updated to 1.4.1
|
||||
- Changed %%define to %%global
|
||||
|
||||
* Thu Oct 08 2009 Paul Wouters <paul@xelerance.com> - 1.3.4-2
|
||||
- Bump version
|
||||
|
||||
* Thu Oct 08 2009 Paul Wouters <paul@xelerance.com> - 1.3.4-1
|
||||
- Upgraded to 1.3.4. Security fix with validating NSEC3 records
|
||||
|
||||
* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 1.3.3-2
|
||||
- rebuilt with new openssl
|
||||
|
||||
* Mon Aug 17 2009 Paul Wouters <paul@xelerance.com> - 1.3.3-1
|
||||
- Updated to 1.3.3
|
||||
|
||||
* Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.3.0-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
|
||||
|
||||
* Sat Jun 20 2009 Paul Wouters <paul@xelerance.com> - 1.3.0-2
|
||||
- Added missing glob patch to cvs
|
||||
- Place python macros within the %%with_python check
|
||||
|
||||
* Sat Jun 20 2009 Paul Wouters <paul@xelerance.com> - 1.3.0-1
|
||||
- Updated to 1.3.0
|
||||
- Added unbound-python sub package. disabled for now
|
||||
- Patch from svn to fix DLV lookups
|
||||
- Patches from svn to detect wrong truncated response from BIND 9.6.1 with
|
||||
minimal-responses)
|
||||
- Added Default-Start and Default-Stop to unbound.init
|
||||
- Re-enabled --enable-sha2
|
||||
- Re-enabled glob.patch
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-7
|
||||
- unbound-iterator.patch was not committed
|
||||
|
||||
* Wed May 20 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-6
|
||||
- Fix for https://bugzilla.redhat.com/show_bug.cgi?id=499793
|
||||
|
||||
* Tue Mar 17 2009 Paul Wouters <paul@xelerance.com> - 1.2.1-5
|
||||
- Use --nocheck to avoid giving an error on missing unbound-remote certs/keys
|
||||
|
||||
* Tue Mar 10 2009 Adam Tkac <atkac redhat com> - 1.2.1-4
|
||||
- enable DNSSEC only if it is enabled in sysconfig/dnssec
|
||||
|
||||
* Mon Mar 09 2009 Adam Tkac <atkac redhat com> - 1.2.1-3
|
||||
- add DNSSEC support to initscript and enabled it per default
|
||||
- add requires dnssec-conf
|
||||
|
||||
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.1-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
|
||||
|
||||
* Tue Feb 10 2009 Paul Wouters <paul@xelerance.com - 1.2.1-1
|
||||
- updated to 1.2.1
|
||||
|
||||
* Sun Jan 18 2009 Tomas Mraz <tmraz@redhat.com> - 1.2.0-2
|
||||
- rebuild with new openssl
|
||||
|
||||
* 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 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)
|
||||
- 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
|
||||
response.
|
||||
- Removed patches (got merged into upstream)
|
||||
|
||||
* Mon Jan 5 2009 Paul Wouters <paul@xelerance.com> - 1.1.1-7
|
||||
- Modified scandir patch to silently fail when wildcard matches nothing
|
||||
- Patch to allow unbound-checkconf to find empty wildcard matches
|
||||
|
||||
* Mon Jan 5 2009 Paul Wouters <paul@xelerance.com> - 1.1.1-6
|
||||
- Added scandir patch for trusted-keys-file: option, which
|
||||
is used to load multiple dnssec keys in bind file format
|
||||
|
||||
* Mon Dec 8 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-4
|
||||
- Added Requires: for selinux-policy >= 3.5.13-33 for proper SElinux rules.
|
||||
|
||||
* Mon Dec 1 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-3
|
||||
- We did not own the /etc/unbound directory (#474020)
|
||||
- Fixed cvs anomalies
|
||||
|
||||
* Fri Nov 28 2008 Adam Tkac <atkac redhat com> - 1.1.1-2
|
||||
- removed all obsolete chroot related stuff
|
||||
- label control certs after generation correctly
|
||||
|
||||
* Thu Nov 20 2008 Paul Wouters <paul@xelerance.com> - 1.1.1-1
|
||||
- Updated to unbound 1.1.1 which fixes a crasher and
|
||||
addresses nlnetlabs bug #219
|
||||
|
||||
* Wed Nov 19 2008 Paul Wouters <paul@xelerance.com> - 1.1.0-3
|
||||
- Remove the chroot, obsoleted by SElinux
|
||||
- Add additional munin plugin links supported by unbound plugin
|
||||
- Move configuration directory from /var/lib/unbound to /etc/unbound
|
||||
- Modified unbound.init and unbound.conf to account for chroot changes
|
||||
- Updated unbound.conf with new available options
|
||||
- Enabled dns-0x20 protection per default
|
||||
|
||||
* Wed Nov 19 2008 Adam Tkac <atkac redhat com> - 1.1.0-2
|
||||
- unbound-1.1.0-log_open.patch
|
||||
- make sure log is opened before chroot call
|
||||
- tracked as http://www.nlnetlabs.nl/bugs/show_bug.cgi?id=219
|
||||
- removed /dev/log and /var/run/unbound and /etc/resolv.conf from
|
||||
chroot, not needed
|
||||
- don't mount files in chroot, it causes problems during updates
|
||||
- fixed typo in default config file
|
||||
|
||||
* Fri Nov 14 2008 Paul Wouters <paul@xelerance.com> - 1.1.0-1
|
||||
- Updated to version 1.1.0
|
||||
- Updated unbound.conf's statistics options and remote-control
|
||||
to work properly for munin
|
||||
- Added unbound-munin package
|
||||
- Generate unbound remote-control key/certs on first startup
|
||||
- Required ldns is now 1.4.0
|
||||
|
||||
* Wed Oct 22 2008 Paul Wouters <paul@xelerance.com> - 1.0.2-5
|
||||
- Only call ldconfig in -libs package
|
||||
- Move configure into build section
|
||||
@@ -423,7 +172,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.
|
||||
@@ -431,3 +180,6 @@ fi
|
||||
|
||||
* Wed Apr 23 2008 Wouter Wijngaards <wouter@nlnetlabs.nl> - 0.11
|
||||
- Initial version.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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.
+88
-119
@@ -1,8 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# plugin for munin to monitor usage of unbound servers.
|
||||
# To install copy this to /usr/local/share/munin/plugins/unbound_munin_
|
||||
# and use munin-node-configure (--suggest, --shell).
|
||||
#
|
||||
# (C) 2008 W.C.A. Wijngaards. BSD Licensed.
|
||||
#
|
||||
@@ -47,9 +45,9 @@
|
||||
# unbound_munin_histogram - histogram of query resolving times
|
||||
#
|
||||
# Magic markers - optional - used by installation scripts and
|
||||
# munin-config: (originally contrib family but munin-node-configure ignores it)
|
||||
# munin-config:
|
||||
#
|
||||
#%# family=auto
|
||||
#%# family=contrib
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
# POD documentation
|
||||
@@ -125,18 +123,8 @@ get_value ( ) {
|
||||
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
|
||||
if test -f $lock ; then
|
||||
pid="`cat $lock 2>&1`"
|
||||
kill -0 "$pid" >/dev/null 2>&1
|
||||
if test $? -ne 0 -a "$pid" != $$ ; then
|
||||
echo $$ >$lock
|
||||
fi
|
||||
fi
|
||||
|
||||
i=0
|
||||
while test ! -f $lock || test "`cat $lock 2>&1`" != $$; do
|
||||
while test ! -f $lock || test "`cat $lock`" != $$; do
|
||||
while test -f $lock; do
|
||||
# wait
|
||||
i=`expr $i + 1`
|
||||
@@ -150,7 +138,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
|
||||
@@ -177,7 +165,7 @@ if test "$1" = "autoconf" ; then
|
||||
exit 1
|
||||
fi
|
||||
if test ! -d `dirname $state`; then
|
||||
echo no "(`dirname $state` directory does not exist)"
|
||||
echo no "($state directory does not exist)"
|
||||
exit 1
|
||||
fi
|
||||
echo yes
|
||||
@@ -210,7 +198,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
|
||||
}
|
||||
|
||||
@@ -219,7 +206,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
|
||||
@@ -230,21 +216,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_vlabel queries / second"
|
||||
echo "graph_category DNS"
|
||||
for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
|
||||
sed -e 's/=.*//'`; do
|
||||
for x in thread0.num.queries thread1.num.queries \
|
||||
thread2.num.queries thread3.num.queries thread4.num.queries \
|
||||
thread5.num.queries thread6.num.queries thread7.num.queries; 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.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 "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."
|
||||
@@ -253,12 +237,11 @@ 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"
|
||||
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)
|
||||
@@ -266,143 +249,124 @@ if test "$1" = "config" ; then
|
||||
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"
|
||||
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_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_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_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_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_vlabel queries / second"
|
||||
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"
|
||||
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_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."
|
||||
@@ -423,6 +387,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 . _`
|
||||
@@ -430,23 +408,15 @@ 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.ipv6 unwanted.queries \
|
||||
unwanted.replies; do
|
||||
for x in thread0.num.queries thread1.num.queries thread2.num.queries \
|
||||
thread3.num.queries thread4.num.queries thread5.num.queries \
|
||||
thread6.num.queries thread7.num.queries total.num.queries \
|
||||
total.num.cachehits num.query.tcp 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
|
||||
;;
|
||||
@@ -457,47 +427,46 @@ 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
|
||||
for x in mem.total.sbrk mem.cache.rrset mem.cache.message \
|
||||
mem.mod.iterator mem.mod.validator; do
|
||||
print_value $x
|
||||
done
|
||||
;;
|
||||
by_type)
|
||||
for x in `grep "^num.query.type" $state`; do
|
||||
nm=`echo $x | sed -e 's/=.*$//'`
|
||||
print_value_line $nm $x
|
||||
print_qps_line $nm $x
|
||||
done
|
||||
;;
|
||||
by_class)
|
||||
for x in `grep "^num.query.class" $state`; do
|
||||
nm=`echo $x | sed -e 's/=.*$//'`
|
||||
print_value_line $nm $x
|
||||
print_qps_line $nm $x
|
||||
done
|
||||
;;
|
||||
by_opcode)
|
||||
for x in `grep "^num.query.opcode" $state`; do
|
||||
nm=`echo $x | sed -e 's/=.*$//'`
|
||||
print_value_line $nm $x
|
||||
print_qps_line $nm $x
|
||||
done
|
||||
;;
|
||||
by_rcode)
|
||||
for x in `grep "^num.answer.rcode" $state`; do
|
||||
nm=`echo $x | sed -e 's/=.*$//'`
|
||||
print_value_line $nm $x
|
||||
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 \
|
||||
@@ -519,21 +488,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 \
|
||||
@@ -554,6 +523,6 @@ histogram)
|
||||
get_value $x
|
||||
r=`expr $r + $value`
|
||||
done
|
||||
echo h16s.value $r
|
||||
echo h16s.value `echo scale=6';' $r / $elapsed | bc `
|
||||
;;
|
||||
esac
|
||||
|
||||
Binary file not shown.
@@ -8,7 +8,7 @@ ubhost=unbound-host
|
||||
|
||||
usage ( )
|
||||
{
|
||||
echo "usage: update-anchor [-r hs] [-b] <zone name> <trust anchor file>"
|
||||
echo "usage: update-anchor [-b] <zone name> <trust anchor file>"
|
||||
echo " performs an update of trust anchor file"
|
||||
echo " the trust anchor file is overwritten with the latest keys"
|
||||
echo " the trust anchor file should contain only keys for one zone"
|
||||
@@ -16,15 +16,13 @@ usage ( )
|
||||
echo " without -b the file is made in unbound format."
|
||||
echo " "
|
||||
echo "alternate:"
|
||||
echo " update-anchor [-r hints] [-b] -d directory"
|
||||
echo " update-anchor [-b] -d directory"
|
||||
echo " update all <zone>.anchor files in the directory."
|
||||
echo " "
|
||||
echo " name the files br.anchor se.anchor ..., and include them in"
|
||||
echo " the validating resolver config file."
|
||||
echo " put keys for the root in a file with the name root.anchor."
|
||||
echo ""
|
||||
echo "-r root.hints use different root hints. Strict option order."
|
||||
echo ""
|
||||
echo "Exit code 0 means anchors updated, 1 no changes, others are errors."
|
||||
exit 2
|
||||
}
|
||||
@@ -34,12 +32,6 @@ if test $# -eq 0; then
|
||||
fi
|
||||
bindformat="no"
|
||||
filearg='-f'
|
||||
roothints=""
|
||||
if test X"$1" = "X-r"; then
|
||||
shift
|
||||
roothints="$1"
|
||||
shift
|
||||
fi
|
||||
if test X"$1" = "X-b"; then
|
||||
shift
|
||||
bindformat="yes"
|
||||
@@ -54,15 +46,10 @@ do_update ( ) {
|
||||
# arguments: <zonename> <keyfile>
|
||||
zonename="$1"
|
||||
keyfile="$2"
|
||||
tmpfile="/tmp/update-anchor.$$"
|
||||
tmp2=$tmpfile.2
|
||||
tmp3=$tmpfile.3
|
||||
rh=""
|
||||
if test -n "$roothints"; then
|
||||
echo "server: root-hints: '$roothints'" > $tmp3
|
||||
rh="-C $tmp3"
|
||||
fi
|
||||
$ubhost -v $rh $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile
|
||||
|
||||
tmpfile="/tmp/update-anchor.$$"
|
||||
$ubhost -v $filearg "$keyfile" -t DNSKEY "$zonename" >$tmpfile
|
||||
if test $? -ne 0; then
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
@@ -78,7 +65,7 @@ do_update ( ) {
|
||||
rm -f $tmpfile
|
||||
echo "Error: Could not update zone $zonename anchor file $keyfile"
|
||||
echo "Cause: result of lookup was not secure"
|
||||
echo " (keys too far out of date? domain changed ownership? need root hints?)"
|
||||
echo " (keys too far out of date? domain changed ownership?)"
|
||||
return 3
|
||||
fi
|
||||
|
||||
@@ -128,7 +115,7 @@ do_update ( ) {
|
||||
echo "$zonename key file $keyfile unchanged."
|
||||
fi
|
||||
|
||||
rm -f $tmpfile $tmp2 $tmp3
|
||||
rm -f $tmpfile $tmp2
|
||||
}
|
||||
|
||||
no_updated=1
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
#!/bin/sh
|
||||
# validation reporter - reports validation failures to a collection server.
|
||||
# Copyright NLnet Labs, 2010
|
||||
# BSD license.
|
||||
|
||||
|
||||
###
|
||||
# Here is the configuration for the validation reporter
|
||||
# it greps the failure lines out of the log and sends them to a server.
|
||||
|
||||
# The pidfile for the reporter daemon.
|
||||
pidfile="/var/run/validation-reporter.pid"
|
||||
|
||||
# The logfile to watch for logged validation failures.
|
||||
logfile="/var/log/unbound.log"
|
||||
|
||||
# how to notify the upstream
|
||||
# nc is netcat, it sends tcp to given host port. It makes a tcp connection
|
||||
# and writes one log-line to it (grepped from the logfile).
|
||||
# the notify command can be: "nc the.server.name.org 1234"
|
||||
# the listening daemon could be: nc -lk 127.0.0.1 1234 >> outputfile &
|
||||
notify_cmd="nc localhost 1234"
|
||||
|
||||
|
||||
###
|
||||
# Below this line is the code for the validation reporter,
|
||||
# first the daemon itself, then the controller for the daemon.
|
||||
reporter_daemon() {
|
||||
trap "rm -f \"$pidfile\"" EXIT
|
||||
tail -F $logfile | grep --line-buffered "unbound.*info: validation failure" | \
|
||||
while read x; do
|
||||
echo "$x" | $notify_cmd
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
###
|
||||
# controller for daemon.
|
||||
start_daemon() {
|
||||
echo "starting reporter"
|
||||
nohup $0 rundaemon </dev/null >/dev/null 2>&1 &
|
||||
echo $! > "$pidfile"
|
||||
}
|
||||
|
||||
kill_daemon() {
|
||||
echo "stopping reporter"
|
||||
if test -s "$pidfile"; then
|
||||
kill `cat "$pidfile"`
|
||||
# check it is really dead
|
||||
if kill -0 `cat "$pidfile"` >/dev/null 2>&1; then
|
||||
sleep 1
|
||||
while kill -0 `cat "$pidfile"` >/dev/null 2>&1; do
|
||||
kill `cat "$pidfile"` >/dev/null 2>&1
|
||||
echo "waiting for reporter to stop"
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
get_status_daemon() {
|
||||
if test -s "$pidfile"; then
|
||||
if kill -0 `cat "$pidfile"`; then
|
||||
return 0;
|
||||
fi
|
||||
fi
|
||||
return 1;
|
||||
}
|
||||
|
||||
restart_daemon() {
|
||||
kill_daemon
|
||||
start_daemon
|
||||
}
|
||||
|
||||
condrestart_daemon() {
|
||||
if get_status_daemon; then
|
||||
echo "reporter ("`cat "$pidfile"`") is running"
|
||||
exit 0
|
||||
fi
|
||||
start_daemon
|
||||
exit 0
|
||||
}
|
||||
|
||||
status_daemon() {
|
||||
if get_status_daemon; then
|
||||
echo "reporter ("`cat "$pidfile"`") is running"
|
||||
exit 0
|
||||
fi
|
||||
echo "reporter is not running"
|
||||
exit 1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
rundaemon)
|
||||
reporter_daemon
|
||||
;;
|
||||
start)
|
||||
start_daemon
|
||||
;;
|
||||
stop)
|
||||
kill_daemon
|
||||
;;
|
||||
restart)
|
||||
restart_daemon
|
||||
;;
|
||||
condrestart)
|
||||
condrestart_daemon
|
||||
;;
|
||||
status)
|
||||
status_daemon
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|condrestart|status}"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
exit $?
|
||||
@@ -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
|
||||
+20
-331
@@ -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,9 @@
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "services/localzone.h"
|
||||
#include "sldns/str2wire.h"
|
||||
|
||||
struct acl_list*
|
||||
acl_list_create(void)
|
||||
acl_list_create()
|
||||
{
|
||||
struct acl_list* acl = (struct acl_list*)calloc(1,
|
||||
sizeof(struct acl_list));
|
||||
@@ -73,21 +71,21 @@ acl_list_delete(struct acl_list* acl)
|
||||
}
|
||||
|
||||
/** insert new address into acl_list structure */
|
||||
static struct acl_addr*
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** apply acl_list string */
|
||||
@@ -105,10 +103,6 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||
control = acl_deny;
|
||||
else if(strcmp(s2, "refuse") == 0)
|
||||
control = acl_refuse;
|
||||
else if(strcmp(s2, "deny_non_local") == 0)
|
||||
control = acl_deny_non_local;
|
||||
else if(strcmp(s2, "refuse_non_local") == 0)
|
||||
control = acl_refuse_non_local;
|
||||
else if(strcmp(s2, "allow_snoop") == 0)
|
||||
control = acl_allow_snoop;
|
||||
else {
|
||||
@@ -127,205 +121,6 @@ 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(struct acl_list* acl, const char* str)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
struct sockaddr_storage addr;
|
||||
int net;
|
||||
socklen_t addrlen;
|
||||
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))) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/** apply acl_tag string */
|
||||
static int
|
||||
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||
size_t bitmaplen)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->taglen = bitmaplen;
|
||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||
if(!node->taglist) {
|
||||
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)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||
if(!node->view) {
|
||||
log_err("no view with name: %s", str2);
|
||||
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)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
enum localzone_type t;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_actions) {
|
||||
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
||||
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)-13,
|
||||
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)
|
||||
{
|
||||
struct acl_addr* node;
|
||||
int tagid;
|
||||
char* dupdata;
|
||||
if(!(node=acl_find_or_create(acl, str)))
|
||||
return 0;
|
||||
/* allocate array if not yet */
|
||||
if(!node->tag_datas) {
|
||||
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
||||
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_file* cfg)
|
||||
@@ -339,114 +134,13 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tags config */
|
||||
static int
|
||||
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_strbytelist* np, *p = cfg->acl_tags;
|
||||
cfg->acl_tags = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
|
||||
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 view config */
|
||||
static int
|
||||
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
||||
{
|
||||
struct config_str2list* np, *p = cfg->acl_view;
|
||||
cfg->acl_view = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2);
|
||||
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
|
||||
return 0;
|
||||
}
|
||||
/* free the items as we go to free up memory */
|
||||
np = p->next;
|
||||
free(p->str);
|
||||
free(p->str2);
|
||||
free(p);
|
||||
p = np;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read acl tag actions config */
|
||||
static int
|
||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
||||
{
|
||||
struct config_str3list* p, *np;
|
||||
p = cfg->acl_tag_actions;
|
||||
cfg->acl_tag_actions = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
|
||||
p->str3)) {
|
||||
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* p, *np;
|
||||
p = cfg->acl_tag_datas;
|
||||
cfg->acl_tag_datas = NULL;
|
||||
while(p) {
|
||||
log_assert(p->str && p->str2 && p->str3);
|
||||
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
|
||||
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)
|
||||
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))
|
||||
return 0;
|
||||
if(!read_acl_view(acl, cfg, v))
|
||||
return 0;
|
||||
if(!read_acl_tags(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_actions(acl, cfg))
|
||||
return 0;
|
||||
if(!read_acl_tag_datas(acl, cfg))
|
||||
return 0;
|
||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
||||
return 0;
|
||||
@@ -465,18 +159,13 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||
}
|
||||
|
||||
enum acl_access
|
||||
acl_get_control(struct acl_addr* acl)
|
||||
{
|
||||
if(acl) return acl->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
struct acl_addr*
|
||||
acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
return (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||
addr, addrlen);
|
||||
if(r) return r->control;
|
||||
return acl_deny;
|
||||
}
|
||||
|
||||
size_t
|
||||
|
||||
+17
-47
@@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,6 @@
|
||||
#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,10 +55,6 @@ 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 */
|
||||
@@ -76,7 +71,7 @@ struct acl_list {
|
||||
* Tree of the addresses that are allowed/blocked.
|
||||
* contents of type acl_addr.
|
||||
*/
|
||||
rbtree_type tree;
|
||||
rbtree_t tree;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -88,28 +83,13 @@ 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
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct acl_list* acl_list_create(void);
|
||||
struct acl_list* acl_list_create();
|
||||
|
||||
/**
|
||||
* Delete acl structure.
|
||||
@@ -121,29 +101,19 @@ void acl_list_delete(struct acl_list* acl);
|
||||
* 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);
|
||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
||||
+236
-278
@@ -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,41 +40,81 @@
|
||||
* to text format.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include <openssl/ssl.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 "util/data/msgreply.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/data/dname.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,
|
||||
uint32_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(SSL* 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, uint32_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(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, time_t now)
|
||||
struct packed_rrset_data* d, uint32_t now)
|
||||
{
|
||||
size_t i;
|
||||
/* rd lock held by caller */
|
||||
@@ -82,23 +122,29 @@ dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
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 %u %u %u %d %d\n",
|
||||
(k->rk.flags & PACKED_RRSET_NSEC_AT_APEX)?" nsec_apex":"",
|
||||
(long long)(d->ttl - now),
|
||||
(unsigned)(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(SSL* ssl, struct lruhash* h, time_t now)
|
||||
dump_rrset_lruhash(SSL* ssl, struct lruhash* h, uint32_t now)
|
||||
{
|
||||
struct lruhash_entry* e;
|
||||
/* lruhash already locked by caller */
|
||||
@@ -138,10 +184,20 @@ dump_rrset_cache(SSL* ssl, struct worker* worker)
|
||||
static int
|
||||
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);
|
||||
@@ -164,16 +220,25 @@ dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
|
||||
/** dump message entry */
|
||||
static int
|
||||
dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
time_t now)
|
||||
uint32_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);
|
||||
@@ -189,10 +254,10 @@ dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
|
||||
}
|
||||
|
||||
/* meta line */
|
||||
if(!ssl_printf(ssl, "msg %s %s %s %d %d " ARG_LL "d %d %u %u %u\n",
|
||||
if(!ssl_printf(ssl, "msg %s %s %s %d %d %u %d %u %u %u\n",
|
||||
nm, cl, tp,
|
||||
(int)d->flags, (int)d->qdcount,
|
||||
(long long)(d->ttl-now), (int)d->security,
|
||||
(unsigned)(d->ttl-now), (int)d->security,
|
||||
(unsigned)d->an_numrrsets,
|
||||
(unsigned)d->ns_numrrsets,
|
||||
(unsigned)d->ar_numrrsets)) {
|
||||
@@ -223,15 +288,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,
|
||||
@@ -301,81 +364,98 @@ dump_cache(SSL* ssl, struct worker* worker)
|
||||
|
||||
/** read a line from ssl into buffer */
|
||||
static int
|
||||
ssl_read_buf(SSL* 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(SSL* 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(SSL* 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)
|
||||
unsigned int i, int is_rrsig, int* go_on, uint32_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) {
|
||||
log_warn("error cannot parse rr: %s: %s",
|
||||
sldns_get_errorstr_parse(status),
|
||||
(char*)sldns_buffer_begin(buf));
|
||||
log_info("rd %s", (char*)ldns_buffer_begin(buf));
|
||||
status = ldns_rr_new_frm_str(&rr, (char*)ldns_buffer_begin(buf),
|
||||
LDNS_DEFAULT_TTL, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot parse rr :%s: %s\n",
|
||||
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) {
|
||||
log_warn("error expected rrsig but got %s",
|
||||
(char*)sldns_buffer_begin(buf));
|
||||
if(is_rrsig && ldns_rr_get_type(rr) != LDNS_RR_TYPE_RRSIG) {
|
||||
(void)ssl_printf(ssl, "error expected rrsig but got %s\n",
|
||||
(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) {
|
||||
(void)ssl_printf(ssl, "error cannot rr2wire :%s\n",
|
||||
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]) {
|
||||
log_warn("error out of memory");
|
||||
ldns_rr_free(rr);
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
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));
|
||||
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");
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
ldns_rr_free(rr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
ldns_rr_free(rr);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** move entry into cache */
|
||||
static int
|
||||
move_into_cache(struct ub_packed_rrset_key* k,
|
||||
move_into_cache(SSL* ssl, struct ub_packed_rrset_key* k,
|
||||
struct packed_rrset_data* d, struct worker* worker)
|
||||
{
|
||||
struct ub_packed_rrset_key* ak;
|
||||
@@ -386,7 +466,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
|
||||
ak = alloc_special_obtain(&worker->alloc);
|
||||
if(!ak) {
|
||||
log_warn("error out of memory");
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
ak->entry.data = NULL;
|
||||
@@ -394,17 +474,16 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
ak->entry.hash = rrset_key_hash(&k->rk);
|
||||
ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
|
||||
if(!ak->rk.dname) {
|
||||
log_warn("error out of memory");
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
ub_packed_rrset_parsedelete(ak, &worker->alloc);
|
||||
return 0;
|
||||
}
|
||||
s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) +
|
||||
sizeof(time_t))* num;
|
||||
sizeof(uint32_t))* num;
|
||||
for(i=0; i<num; i++)
|
||||
s += d->rr_len[i];
|
||||
ad = (struct packed_rrset_data*)malloc(s);
|
||||
if(!ad) {
|
||||
log_warn("error out of memory");
|
||||
ub_packed_rrset_parsedelete(ak, &worker->alloc);
|
||||
return 0;
|
||||
}
|
||||
@@ -415,8 +494,8 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
p += sizeof(size_t)*num;
|
||||
memmove(p, &d->rr_data[0], sizeof(uint8_t*)*num);
|
||||
p += sizeof(uint8_t*)*num;
|
||||
memmove(p, &d->rr_ttl[0], sizeof(time_t)*num);
|
||||
p += sizeof(time_t)*num;
|
||||
memmove(p, &d->rr_ttl[0], sizeof(uint32_t)*num);
|
||||
p += sizeof(uint32_t)*num;
|
||||
for(i=0; i<num; i++) {
|
||||
memmove(p, d->rr_data[i], d->rr_len[i]);
|
||||
p += d->rr_len[i];
|
||||
@@ -434,14 +513,13 @@ move_into_cache(struct ub_packed_rrset_key* k,
|
||||
|
||||
/** load an rrset entry */
|
||||
static int
|
||||
load_rrset(SSL* 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;
|
||||
unsigned int rr_count, rrsig_count, trust, security;
|
||||
long long ttl;
|
||||
unsigned int ttl, rr_count, rrsig_count, trust, security;
|
||||
unsigned int i;
|
||||
int go_on = 1;
|
||||
regional_free_all(region);
|
||||
@@ -450,12 +528,13 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
sizeof(*rk));
|
||||
d = (struct packed_rrset_data*)regional_alloc_zero(region, sizeof(*d));
|
||||
if(!rk || !d) {
|
||||
log_warn("error out of memory");
|
||||
(void) ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strncmp(s, ";rrset", 6) != 0) {
|
||||
log_warn("error expected ';rrset' but got %s", s);
|
||||
(void)ssl_printf(ssl, "error expected ';rrset' but got %s\n",
|
||||
s);
|
||||
return 0;
|
||||
}
|
||||
s += 6;
|
||||
@@ -463,33 +542,27 @@ load_rrset(SSL* 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, " %u %u %u %u %u", &ttl, &rr_count, &rrsig_count,
|
||||
&trust, &security) != 5) {
|
||||
log_warn("error bad rrset spec %s", s);
|
||||
(void)ssl_printf(ssl, "error bad rrset spec %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
if(rr_count == 0 && rrsig_count == 0) {
|
||||
log_warn("bad rrset without contents");
|
||||
if(rr_count == 0 && rrsig_count == 0)
|
||||
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;
|
||||
d->trust = (enum rrset_trust)trust;
|
||||
d->ttl = (time_t)ttl + *worker->env.now;
|
||||
d->ttl = (uint32_t)ttl + *worker->env.now;
|
||||
|
||||
d->rr_len = regional_alloc_zero(region,
|
||||
sizeof(size_t)*(d->count+d->rrsig_count));
|
||||
d->rr_ttl = regional_alloc_zero(region,
|
||||
sizeof(time_t)*(d->count+d->rrsig_count));
|
||||
sizeof(uint32_t)*(d->count+d->rrsig_count));
|
||||
d->rr_data = regional_alloc_zero(region,
|
||||
sizeof(uint8_t*)*(d->count+d->rrsig_count));
|
||||
if(!d->rr_len || !d->rr_ttl || !d->rr_data) {
|
||||
log_warn("error out of memory");
|
||||
(void) ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -497,14 +570,12 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
for(i=0; i<rr_count; i++) {
|
||||
if(!load_rr(ssl, buf, region, rk, d, i, 0,
|
||||
&go_on, *worker->env.now)) {
|
||||
log_warn("could not read rr %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(i=0; i<rrsig_count; i++) {
|
||||
if(!load_rr(ssl, buf, region, rk, d, i+rr_count, 1,
|
||||
&go_on, *worker->env.now)) {
|
||||
log_warn("could not read rrsig %u", i);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -513,17 +584,17 @@ load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return move_into_cache(rk, d, worker);
|
||||
return move_into_cache(ssl, rk, d, worker);
|
||||
}
|
||||
|
||||
/** load rrset cache */
|
||||
static int
|
||||
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;
|
||||
}
|
||||
@@ -532,40 +603,48 @@ load_rrset_cache(SSL* 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, SSL* ssl)
|
||||
{
|
||||
/* 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, ' ');
|
||||
if(s) s = strchr(s+1, ' ');
|
||||
if(s) s = strchr(s+1, ' ');
|
||||
if(!s) {
|
||||
log_warn("error line too short, %s", str);
|
||||
(void)ssl_printf(ssl, "error line too short, %s\n", str);
|
||||
return NULL;
|
||||
}
|
||||
s[0] = 0;
|
||||
s++;
|
||||
|
||||
/* parse them */
|
||||
status = sldns_str2wire_rr_question_buf(str, rr, &rr_len, &dname_len,
|
||||
NULL, 0, NULL, 0);
|
||||
if(status != 0) {
|
||||
log_warn("error cannot parse: %s %s",
|
||||
sldns_get_errorstr_parse(status), str);
|
||||
status = ldns_rr_new_question_frm_str(&rr, str, NULL, NULL);
|
||||
if(status != LDNS_STATUS_OK) {
|
||||
(void)ssl_printf(ssl, "error cannot parse: %s %s\n",
|
||||
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) {
|
||||
(void)ssl_printf(ssl, "error cannot dname2wire: %s\n",
|
||||
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");
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -574,11 +653,11 @@ load_qinfo(char* str, struct query_info* qinfo, struct regional* region)
|
||||
|
||||
/** load a msg rrset reference */
|
||||
static int
|
||||
load_ref(SSL* 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;
|
||||
@@ -591,12 +670,12 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
return 1;
|
||||
}
|
||||
|
||||
s = load_qinfo(s, &qinfo, region);
|
||||
s = load_qinfo(s, &qinfo, buf, region, ssl);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
if(sscanf(s, " %u", &flags) != 1) {
|
||||
log_warn("error cannot parse flags: %s", s);
|
||||
(void)ssl_printf(ssl, "error cannot parse flags: %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -619,44 +698,38 @@ load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
|
||||
|
||||
/** load a msg entry */
|
||||
static int
|
||||
load_msg(SSL* 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);
|
||||
unsigned int flags, qdcount, security, an, ns, ar;
|
||||
long long ttl;
|
||||
char* s = (char*)ldns_buffer_begin(buf);
|
||||
unsigned int flags, qdcount, ttl, security, an, ns, ar;
|
||||
size_t i;
|
||||
int go_on = 1;
|
||||
|
||||
regional_free_all(region);
|
||||
|
||||
if(strncmp(s, "msg ", 4) != 0) {
|
||||
log_warn("error expected msg but got %s", s);
|
||||
(void)ssl_printf(ssl, "error expected msg but got %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
s += 4;
|
||||
s = load_qinfo(s, &qinf, region);
|
||||
s = load_qinfo(s, &qinf, buf, region, ssl);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read remainder of line */
|
||||
if(sscanf(s, " %u %u " ARG_LL "d %u %u %u %u", &flags, &qdcount, &ttl,
|
||||
if(sscanf(s, " %u %u %u %u %u %u %u", &flags, &qdcount, &ttl,
|
||||
&security, &an, &ns, &ar) != 7) {
|
||||
log_warn("error cannot parse numbers: %s", s);
|
||||
(void)ssl_printf(ssl, "error cannot parse numbers: %s\n", s);
|
||||
return 0;
|
||||
}
|
||||
rep.flags = (uint16_t)flags;
|
||||
rep.qdcount = (uint16_t)qdcount;
|
||||
rep.ttl = (time_t)ttl;
|
||||
rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
|
||||
rep.ttl = (uint32_t)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;
|
||||
@@ -675,8 +748,8 @@ load_msg(SSL* 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)) {
|
||||
log_warn("error out of memory");
|
||||
if(!dns_cache_store(&worker->env, &qinf, &rep, 0)) {
|
||||
(void)ssl_printf(ssl, "error out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -686,10 +759,10 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
|
||||
static int
|
||||
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;
|
||||
}
|
||||
@@ -706,112 +779,6 @@ load_cache(SSL* ssl, struct worker* worker)
|
||||
return read_fixed(ssl, worker->env.scratch_buffer, "EOF");
|
||||
}
|
||||
|
||||
/** print details on a delegation point */
|
||||
static void
|
||||
print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
|
||||
{
|
||||
char buf[257];
|
||||
struct delegpt_addr* a;
|
||||
int lame, dlame, rlame, rto, edns_vs, to, delay,
|
||||
tA = 0, tAAAA = 0, tother = 0;
|
||||
long long entry_ttl;
|
||||
struct rtt_info ri;
|
||||
uint8_t edns_lame_known;
|
||||
for(a = dp->target_list; a; a = a->next_target) {
|
||||
addr_to_str(&a->addr, a->addrlen, buf, sizeof(buf));
|
||||
if(!ssl_printf(ssl, "%-16s\t", buf))
|
||||
return;
|
||||
if(a->bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS. "))
|
||||
return;
|
||||
}
|
||||
/* lookup in infra cache */
|
||||
delay=0;
|
||||
entry_ttl = infra_get_host_rto(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, dp->name, dp->namelen,
|
||||
&ri, &delay, *worker->env.now, &tA, &tAAAA, &tother);
|
||||
if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
|
||||
if(!ssl_printf(ssl, "expired, rto %d msec, tA %d "
|
||||
"tAAAA %d tother %d.\n", ri.rto, tA, tAAAA,
|
||||
tother))
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if(entry_ttl == -1 || entry_ttl == -2) {
|
||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||
return;
|
||||
continue; /* skip stuff not in infra cache */
|
||||
}
|
||||
|
||||
/* uses type_A because most often looked up, but other
|
||||
* lameness won't be reported then */
|
||||
if(!infra_get_lame_rtt(worker->env.infra_cache,
|
||||
&a->addr, a->addrlen, dp->name, dp->namelen,
|
||||
LDNS_RR_TYPE_A, &lame, &dlame, &rlame, &rto,
|
||||
*worker->env.now)) {
|
||||
if(!ssl_printf(ssl, "not in infra cache.\n"))
|
||||
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",
|
||||
lame?"LAME ":"", dlame?"NoDNSSEC ":"",
|
||||
a->lame?"AddrWasParentSide ":"",
|
||||
rlame?"NoAuthButRecursive ":"", rto, entry_ttl,
|
||||
ri.srtt, ri.rttvar, rtt_notimeout(&ri),
|
||||
tA, tAAAA, tother))
|
||||
return;
|
||||
if(delay)
|
||||
if(!ssl_printf(ssl, ", probedelay %d", delay))
|
||||
return;
|
||||
if(infra_host(worker->env.infra_cache, &a->addr, a->addrlen,
|
||||
dp->name, dp->namelen, *worker->env.now, &edns_vs,
|
||||
&edns_lame_known, &to)) {
|
||||
if(edns_vs == -1) {
|
||||
if(!ssl_printf(ssl, ", noEDNS%s.",
|
||||
edns_lame_known?" probed":" assumed"))
|
||||
return;
|
||||
} else {
|
||||
if(!ssl_printf(ssl, ", EDNS %d%s.", edns_vs,
|
||||
edns_lame_known?" probed":" assumed"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(!ssl_printf(ssl, "\n"))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** print main dp info */
|
||||
static void
|
||||
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;
|
||||
|
||||
/* print the dp */
|
||||
if(msg)
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)k->entry.data;
|
||||
if(d->security == sec_status_bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
|
||||
return;
|
||||
}
|
||||
if(!dump_rrset(ssl, k, d, 0))
|
||||
return;
|
||||
}
|
||||
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||
/* since dp has not been used by iterator, all are available*/
|
||||
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
|
||||
"can be examined to query further addresses.\n"
|
||||
"%sIt provides %d IP addresses.\n",
|
||||
(int)n_ns, (int)n_miss, (dp->bogus?"It is BOGUS. ":""),
|
||||
(int)n_addr))
|
||||
return;
|
||||
}
|
||||
|
||||
int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
size_t nmlen, int ATTR_UNUSED(nmlabs))
|
||||
{
|
||||
@@ -821,28 +788,18 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
struct regional* region = worker->scratchpad;
|
||||
char b[260];
|
||||
struct query_info qinfo;
|
||||
struct iter_hints_stub* stub;
|
||||
size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
|
||||
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);
|
||||
if(dp) {
|
||||
if(!ssl_printf(ssl, "forwarding request:\n"))
|
||||
return 0;
|
||||
print_dp_main(ssl, dp, NULL);
|
||||
print_dp_details(ssl, worker, dp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
dp = dns_cache_find_delegation(&worker->env, nm, nmlen,
|
||||
qinfo.qtype, qinfo.qclass, region, &msg,
|
||||
@@ -851,10 +808,29 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
return ssl_printf(ssl, "no delegation from "
|
||||
"cache; goes to configured roots\n");
|
||||
}
|
||||
/* print the dp */
|
||||
for(i=0; i<msg->rep->rrset_count; i++) {
|
||||
struct ub_packed_rrset_key* k = msg->rep->rrsets[i];
|
||||
struct packed_rrset_data* d =
|
||||
(struct packed_rrset_data*)k->entry.data;
|
||||
if(d->security == sec_status_bogus) {
|
||||
if(!ssl_printf(ssl, "Address is BOGUS:\n"))
|
||||
return 0;
|
||||
}
|
||||
if(!dump_rrset(ssl, k, d, 0))
|
||||
return 0;
|
||||
}
|
||||
delegpt_count_ns(dp, &n_ns, &n_miss);
|
||||
delegpt_count_addr(dp, &n_addr, &n_res, &n_avail);
|
||||
/* since dp has not been used by iterator, all are available*/
|
||||
if(!ssl_printf(ssl, "Delegation with %d names, of which %d "
|
||||
"have no addresses in cache.\n"
|
||||
"It provides %d IP addresses. %s\n",
|
||||
(int)n_ns, (int)n_miss, (int)n_addr,
|
||||
(dp->bogus?"It is BOGUS":"") ))
|
||||
return 0;
|
||||
/* go up? */
|
||||
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 "
|
||||
"useless (no IP addresses)\n"))
|
||||
return 0;
|
||||
@@ -872,26 +848,8 @@ int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
|
||||
return 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
stub = hints_lookup_stub(worker->env.hints, nm, qinfo.qclass,
|
||||
dp);
|
||||
if(stub) {
|
||||
if(stub->noprime) {
|
||||
if(!ssl_printf(ssl, "The noprime stub servers "
|
||||
"are used:\n"))
|
||||
return 0;
|
||||
} else {
|
||||
if(!ssl_printf(ssl, "The stub is primed "
|
||||
"with servers:\n"))
|
||||
return 0;
|
||||
}
|
||||
print_dp_main(ssl, stub->dp, NULL);
|
||||
print_dp_details(ssl, worker, stub->dp);
|
||||
} else {
|
||||
print_dp_main(ssl, dp, msg);
|
||||
print_dp_details(ssl, worker, dp);
|
||||
}
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+10
-10
@@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
+35
-324
@@ -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,32 +40,6 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_OPENSSL_ERR_H
|
||||
#include <openssl/err.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_RAND_H
|
||||
#include <openssl/rand.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_CONF_H
|
||||
#include <openssl/conf.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL_ENGINE_H
|
||||
#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 "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/remote.h"
|
||||
@@ -73,41 +47,22 @@
|
||||
#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 "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 "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 <signal.h>
|
||||
|
||||
#ifdef HAVE_SYSTEMD
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
/** How many quit requests happened. */
|
||||
static int sig_record_quit = 0;
|
||||
/** How many reload requests happened. */
|
||||
static int sig_record_reload = 0;
|
||||
|
||||
#if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/** 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.
|
||||
* @param sig: signal number.
|
||||
@@ -116,9 +71,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)
|
||||
@@ -143,8 +97,7 @@ static RETSIGTYPE record_sigh(int sig)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* ignoring signal */
|
||||
break;
|
||||
log_err("ignoring signal %d", sig);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +106,7 @@ static RETSIGTYPE record_sigh(int sig)
|
||||
* Stores signals to replay later.
|
||||
*/
|
||||
static void
|
||||
signal_handling_record(void)
|
||||
signal_handling_record()
|
||||
{
|
||||
if( signal(SIGTERM, record_sigh) == SIG_ERR ||
|
||||
#ifdef SIGQUIT
|
||||
@@ -181,15 +134,8 @@ static void
|
||||
signal_handling_playback(struct worker* wrk)
|
||||
{
|
||||
#ifdef SIGHUP
|
||||
if(sig_record_reload) {
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "RELOADING=1");
|
||||
# endif
|
||||
if(sig_record_reload)
|
||||
worker_sighandler(SIGHUP, wrk);
|
||||
# ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "READY=1");
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
if(sig_record_quit)
|
||||
worker_sighandler(SIGTERM, wrk);
|
||||
@@ -198,7 +144,7 @@ signal_handling_playback(struct worker* wrk)
|
||||
}
|
||||
|
||||
struct daemon*
|
||||
daemon_init(void)
|
||||
daemon_init()
|
||||
{
|
||||
struct daemon* daemon = (struct daemon*)calloc(1,
|
||||
sizeof(struct daemon));
|
||||
@@ -217,44 +163,14 @@ 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
|
||||
ERR_load_SSL_strings();
|
||||
# ifdef USE_GOST
|
||||
(void)sldns_key_EVP_load_gost_id();
|
||||
# endif
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
|
||||
OpenSSL_add_all_algorithms();
|
||||
# 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(0, NULL);
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
if(!ub_openssl_lock_init())
|
||||
fatal_exit("could not init openssl locks");
|
||||
# endif
|
||||
#elif defined(HAVE_NSS)
|
||||
if(NSS_NoDB_Init(NULL) != SECSuccess)
|
||||
fatal_exit("could not init NSS");
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
#ifdef HAVE_TZSET
|
||||
/* 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,
|
||||
@@ -262,16 +178,9 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
/* 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;
|
||||
@@ -287,56 +196,9 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
if(daemon->cfg->port != daemon->listening_port) {
|
||||
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;
|
||||
}
|
||||
/* 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, &daemon->reuseport);
|
||||
if(!p0) {
|
||||
listening_ports_free(p0);
|
||||
listening_ports_free(daemon->ports);
|
||||
if(!(daemon->ports=listening_ports_open(daemon->cfg)))
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
daemon->ports[0] = p0;
|
||||
if(daemon->reuseport) {
|
||||
/* continue to use reuseport */
|
||||
for(i=1; i<daemon->num_ports; i++) {
|
||||
if(!(daemon->ports[i]=
|
||||
listening_ports_open(daemon->cfg,
|
||||
&daemon->reuseport))
|
||||
|| !daemon->reuseport ) {
|
||||
for(i=0; i<daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
daemon->ports = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
daemon->listening_port = daemon->cfg->port;
|
||||
}
|
||||
if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
|
||||
@@ -368,7 +230,6 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
}
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -378,7 +239,7 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
* @param shufport: the portlist output.
|
||||
* @return number of ports available.
|
||||
*/
|
||||
static int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
{
|
||||
int i, n, k, temp;
|
||||
int avail = 0;
|
||||
@@ -394,7 +255,7 @@ static int daemon_get_shufport(struct daemon* daemon, int* shufport)
|
||||
/* Knuth shuffle */
|
||||
n = avail;
|
||||
while(--n > 0) {
|
||||
k = ub_random_max(daemon->rand, n+1); /* 0<= k<= n */
|
||||
k = ub_random(daemon->rand) % (n+1); /* 0<= k<= n */
|
||||
temp = shufport[k];
|
||||
shufport[k] = shufport[n];
|
||||
shufport[n] = temp;
|
||||
@@ -422,35 +283,15 @@ daemon_create_workers(struct daemon* daemon)
|
||||
if(!daemon->rand)
|
||||
fatal_exit("could not init random generator");
|
||||
}
|
||||
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");
|
||||
numport = daemon_get_shufport(daemon, shufport);
|
||||
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->num = daemon->cfg->num_threads;
|
||||
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->dnstap_socket_path,
|
||||
(unsigned int)daemon->num);
|
||||
if (!daemon->dtenv)
|
||||
fatal_exit("dt_create failed");
|
||||
dt_apply_cfg(daemon->dtenv, daemon->cfg);
|
||||
#else
|
||||
fatal_exit("dnstap enabled in config but not built with dnstap support");
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
@@ -461,13 +302,12 @@ daemon_create_workers(struct daemon* daemon)
|
||||
free(shufport);
|
||||
}
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
/**
|
||||
* Close all pipes except for the numbered thread.
|
||||
* @param daemon: daemon to close pipes in.
|
||||
* @param thr: thread number 0..num-1 of thread to skip.
|
||||
*/
|
||||
static void close_other_pipes(struct daemon* daemon, int thr)
|
||||
void close_other_pipes(struct daemon* daemon, int thr)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<daemon->num; i++)
|
||||
@@ -482,7 +322,6 @@ static void close_other_pipes(struct daemon* daemon, int thr)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
/**
|
||||
* Function to start one thread.
|
||||
@@ -493,7 +332,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
|
||||
@@ -501,14 +339,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);
|
||||
@@ -563,63 +394,25 @@ daemon_stop_others(struct daemon* daemon)
|
||||
void
|
||||
daemon_fork(struct daemon* daemon)
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
|
||||
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(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");
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
*/
|
||||
daemon_create_workers(daemon);
|
||||
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
#ifdef HAVE_EV_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
|
||||
|
||||
@@ -631,33 +424,21 @@ daemon_fork(struct daemon* daemon)
|
||||
/* Special handling for the main thread. This is the thread
|
||||
* that handles signals and remote control.
|
||||
*/
|
||||
#if !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP))
|
||||
#ifndef HAVE_EV_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
|
||||
sd_notify(0, "READY=1");
|
||||
#endif
|
||||
log_info("start of service (%s).", PACKAGE_STRING);
|
||||
worker_work(daemon->workers[0]);
|
||||
#ifdef HAVE_SYSTEMD
|
||||
sd_notify(0, "STOPPING=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->need_to_exit = daemon->workers[0]->need_to_exit;
|
||||
}
|
||||
|
||||
@@ -672,45 +453,33 @@ 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 */
|
||||
* 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;
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
/* key cache is cleared by module desetup during next daemon_init() */
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
free(daemon->workers);
|
||||
daemon->workers = NULL;
|
||||
daemon->num = 0;
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
daemon_delete(struct daemon* daemon)
|
||||
{
|
||||
size_t i;
|
||||
if(!daemon)
|
||||
return;
|
||||
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);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
@@ -718,49 +487,15 @@ daemon_delete(struct daemon* daemon)
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->env);
|
||||
#ifdef HAVE_SSL
|
||||
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) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
|
||||
sldns_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
|
||||
/* CONF_modules_unload(1); */
|
||||
EVP_cleanup();
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000
|
||||
ENGINE_cleanup();
|
||||
# endif
|
||||
CONF_modules_free();
|
||||
# endif
|
||||
# ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
|
||||
/* ENGINE_cleanup(); */
|
||||
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
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_Shutdown();
|
||||
#endif /* HAVE_SSL or HAVE_NSS */
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
if(WSACleanup() != 0) {
|
||||
@@ -769,27 +504,3 @@ daemon_delete(struct daemon* daemon)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
daemon->cfg = cfg;
|
||||
config_apply(cfg);
|
||||
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,
|
||||
msgreply_sizefunc, query_info_compare,
|
||||
query_entry_delete, reply_info_delete, NULL);
|
||||
if(!daemon->env->msg_cache) {
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
}
|
||||
if((daemon->env->rrset_cache = rrset_cache_adjust(
|
||||
daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache,
|
||||
cfg))==0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
|
||||
+14
-59
@@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -53,21 +53,7 @@ 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,21 +68,12 @@ 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;
|
||||
/** port number for remote that has ports opened. */
|
||||
/** listening ports, opened, to be shared by threads */
|
||||
struct listen_port* ports;
|
||||
/** port number fore remote that has ports opened. */
|
||||
int rc_port;
|
||||
/** listening ports for remote control */
|
||||
struct listen_port* rc_ports;
|
||||
/** remote control connections management (for first worker) */
|
||||
struct daemon_remote* rc;
|
||||
/** ssl context for listening to dnstcp over ssl, and connecting ssl */
|
||||
void* listen_sslctx, *connect_sslctx;
|
||||
/** num threads allocated */
|
||||
int num;
|
||||
/** the worker entries */
|
||||
@@ -119,28 +96,13 @@ struct daemon {
|
||||
struct timeval time_last_stat;
|
||||
/** time when daemon started */
|
||||
struct timeval time_boot;
|
||||
/** views structure containing view tree */
|
||||
struct views* views;
|
||||
#ifdef USE_DNSTAP
|
||||
/** the dnstap environment master value, copied and changed by threads*/
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
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;
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** the dnscrypt environment */
|
||||
struct dnsc_env* dnscenv;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize daemon structure.
|
||||
* @return: The daemon structure, or NULL on error.
|
||||
*/
|
||||
struct daemon* daemon_init(void);
|
||||
struct daemon* daemon_init();
|
||||
|
||||
/**
|
||||
* Open shared listening ports (if needed).
|
||||
@@ -170,11 +132,4 @@ void daemon_cleanup(struct daemon* daemon);
|
||||
*/
|
||||
void daemon_delete(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Apply config settings.
|
||||
* @param daemon: the daemon.
|
||||
* @param cfg: new config settings.
|
||||
*/
|
||||
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
|
||||
|
||||
#endif /* DAEMON_H */
|
||||
|
||||
+319
-1953
File diff suppressed because it is too large
Load Diff
+21
-46
@@ -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,9 +45,6 @@
|
||||
|
||||
#ifndef DAEMON_REMOTE_H
|
||||
#define DAEMON_REMOTE_H
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
#include "openssl/ssl.h"
|
||||
#endif
|
||||
struct config_file;
|
||||
struct listen_list;
|
||||
struct listen_port;
|
||||
@@ -56,8 +53,8 @@ struct comm_reply;
|
||||
struct comm_point;
|
||||
struct daemon_remote;
|
||||
|
||||
/** number of milliseconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120000
|
||||
/** number of seconds timeout on incoming remote control handshake */
|
||||
#define REMOTE_CONTROL_TCP_TIMEOUT 120
|
||||
|
||||
/**
|
||||
* a busy control command connection, SSL state
|
||||
@@ -69,10 +66,8 @@ struct rc_state {
|
||||
struct comm_point* c;
|
||||
/** in the handshake part */
|
||||
enum { rc_none, rc_hs_read, rc_hs_write } shake_state;
|
||||
#ifdef HAVE_SSL
|
||||
/** the ssl state */
|
||||
SSL* ssl;
|
||||
#endif
|
||||
/** the rc this is part of */
|
||||
struct daemon_remote* rc;
|
||||
};
|
||||
@@ -89,26 +84,22 @@ struct daemon_remote {
|
||||
struct worker* worker;
|
||||
/** commpoints for accepting remote control connections */
|
||||
struct listen_list* accept_list;
|
||||
/* if certificates are used */
|
||||
int use_cert;
|
||||
/** number of active commpoints that are handling remote control */
|
||||
int active;
|
||||
/** max active commpoints */
|
||||
int max_active;
|
||||
/** current commpoints busy; should be a short list, malloced */
|
||||
struct rc_state* busy_list;
|
||||
#ifdef HAVE_SSL
|
||||
/** the SSL context for creating new SSL streams */
|
||||
SSL_CTX* ctx;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new remote control state for the daemon.
|
||||
* @param cfg: config file with key file settings.
|
||||
* @param worker: worker with communication base. and links to command channels.
|
||||
* @return new state, or NULL on failure.
|
||||
*/
|
||||
struct daemon_remote* daemon_remote_create(struct config_file* cfg);
|
||||
struct daemon_remote* daemon_remote_create(struct worker* worker);
|
||||
|
||||
/**
|
||||
* remote control state to delete.
|
||||
@@ -116,13 +107,6 @@ struct daemon_remote* daemon_remote_create(struct config_file* cfg);
|
||||
*/
|
||||
void daemon_remote_delete(struct daemon_remote* rc);
|
||||
|
||||
/**
|
||||
* remote control state to clear up. Busy and accept points are closed.
|
||||
* Does not delete the rc itself, or the ssl context (with its keys).
|
||||
* @param rc: state to clear.
|
||||
*/
|
||||
void daemon_remote_clear(struct daemon_remote* rc);
|
||||
|
||||
/**
|
||||
* Open and create listening ports for remote control.
|
||||
* @param cfg: config options.
|
||||
@@ -135,23 +119,10 @@ struct listen_port* daemon_remote_open_ports(struct config_file* cfg);
|
||||
* Setup comm points for accepting remote control connections.
|
||||
* @param rc: state
|
||||
* @param ports: already opened ports.
|
||||
* @param worker: worker with communication base. and links to command channels.
|
||||
* @return false on error.
|
||||
*/
|
||||
int daemon_remote_open_accept(struct daemon_remote* rc,
|
||||
struct listen_port* ports, struct worker* worker);
|
||||
|
||||
/**
|
||||
* Stop accept handlers for TCP (until enabled again)
|
||||
* @param rc: state
|
||||
*/
|
||||
void daemon_remote_stop_accept(struct daemon_remote* rc);
|
||||
|
||||
/**
|
||||
* Stop accept handlers for TCP (until enabled again)
|
||||
* @param rc: state
|
||||
*/
|
||||
void daemon_remote_start_accept(struct daemon_remote* rc);
|
||||
struct listen_port* ports);
|
||||
|
||||
/**
|
||||
* Handle nonthreaded remote cmd execution.
|
||||
@@ -159,7 +130,12 @@ void daemon_remote_start_accept(struct daemon_remote* rc);
|
||||
*/
|
||||
void daemon_remote_exec(struct worker* worker);
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/** handle remote control accept callbacks */
|
||||
int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*);
|
||||
|
||||
/** handle remote control data callbacks */
|
||||
int remote_control_callback(struct comm_point*, void*, int, struct comm_reply*);
|
||||
|
||||
/**
|
||||
* Print fixed line of text over ssl connection in blocking mode
|
||||
* @param ssl: print to
|
||||
@@ -186,6 +162,5 @@ int ssl_printf(SSL* ssl, const char* format, ...)
|
||||
* @return false on connection failure.
|
||||
*/
|
||||
int ssl_read_line(SSL* ssl, char* buf, size_t max);
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#endif /* DAEMON_REMOTE_H */
|
||||
|
||||
+33
-88
@@ -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,26 +40,16 @@
|
||||
* numbers. These 'statistics' may be of interest to the operator.
|
||||
*/
|
||||
#include "config.h"
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include "daemon/stats.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/timehist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "validator/validator.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "validator/val_kcache.h"
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
@@ -68,7 +58,7 @@ timeval_add(struct timeval* d, const struct timeval* add)
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
if(d->tv_usec > 1000000) {
|
||||
while(d->tv_usec > 1000000 ) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
@@ -89,36 +79,21 @@ void server_stats_querymiss(struct server_stats* stats, struct worker* worker)
|
||||
stats->max_query_list_size = worker->env.mesh->all.count;
|
||||
}
|
||||
|
||||
void server_stats_prefetch(struct server_stats* stats, struct worker* worker)
|
||||
{
|
||||
stats->num_queries_prefetch++;
|
||||
/* changes the query list size so account that, like a querymiss */
|
||||
stats->sum_query_list_size += worker->env.mesh->all.count;
|
||||
if(worker->env.mesh->all.count > stats->max_query_list_size)
|
||||
stats->max_query_list_size = worker->env.mesh->all.count;
|
||||
}
|
||||
|
||||
void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
int threadnum)
|
||||
{
|
||||
log_info("server stats for thread %d: %u queries, "
|
||||
"%u answers from cache, %u recursions, %u prefetch, %u rejected by "
|
||||
"ip ratelimiting",
|
||||
"%u answers from cache, %u recursions",
|
||||
threadnum, (unsigned)stats->num_queries,
|
||||
(unsigned)(stats->num_queries -
|
||||
stats->num_queries_missed_cache),
|
||||
(unsigned)stats->num_queries_missed_cache,
|
||||
(unsigned)stats->num_queries_prefetch,
|
||||
(unsigned)stats->num_queries_ip_ratelimited);
|
||||
(unsigned)stats->num_queries_missed_cache);
|
||||
log_info("server stats for thread %d: requestlist max %u avg %g "
|
||||
"exceeded %u jostled %u", threadnum,
|
||||
(unsigned)stats->max_query_list_size,
|
||||
(stats->num_queries_missed_cache+stats->num_queries_prefetch)?
|
||||
"exceeded %u", threadnum, (unsigned)stats->max_query_list_size,
|
||||
stats->num_queries_missed_cache?
|
||||
(double)stats->sum_query_list_size/
|
||||
(stats->num_queries_missed_cache+
|
||||
stats->num_queries_prefetch) : 0.0,
|
||||
(unsigned)worker->env.mesh->stats_dropped,
|
||||
(unsigned)worker->env.mesh->stats_jostled);
|
||||
stats->num_queries_missed_cache : 0.0,
|
||||
(unsigned)worker->env.mesh->stats_dropped);
|
||||
}
|
||||
|
||||
/** get rrsets bogus number from validator */
|
||||
@@ -140,10 +115,9 @@ get_rrset_bogus(struct worker* worker)
|
||||
}
|
||||
|
||||
void
|
||||
server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
|
||||
server_stats_compile(struct worker* worker, struct stats_info* s)
|
||||
{
|
||||
int i;
|
||||
struct listen_list* lp;
|
||||
|
||||
s->svr = worker->stats;
|
||||
s->mesh_num_states = worker->env.mesh->all.count;
|
||||
@@ -165,46 +139,30 @@ server_stats_compile(struct worker* worker, struct stats_info* s, int reset)
|
||||
NUM_BUCKETS_HIST);
|
||||
/* values from outside network */
|
||||
s->svr.unwanted_replies = worker->back->unwanted_replies;
|
||||
s->svr.qtcp_outgoing = worker->back->num_tcp_outgoing;
|
||||
|
||||
/* get and reset validator rrset bogus number */
|
||||
s->svr.rrset_bogus = get_rrset_bogus(worker);
|
||||
|
||||
/* get cache sizes */
|
||||
s->svr.msg_cache_count = count_slabhash_entries(worker->env.msg_cache);
|
||||
s->svr.rrset_cache_count = count_slabhash_entries(&worker->env.rrset_cache->table);
|
||||
s->svr.infra_cache_count = count_slabhash_entries(worker->env.infra_cache->hosts);
|
||||
if(worker->env.key_cache)
|
||||
s->svr.key_cache_count = count_slabhash_entries(worker->env.key_cache->slab);
|
||||
else s->svr.key_cache_count = 0;
|
||||
|
||||
/* get tcp accept usage */
|
||||
s->svr.tcp_accept_usage = 0;
|
||||
for(lp = worker->front->cps; lp; lp = lp->next) {
|
||||
if(lp->com->type == comm_tcp_accept)
|
||||
s->svr.tcp_accept_usage += lp->com->cur_tcp_count;
|
||||
}
|
||||
|
||||
if(reset && !worker->env.cfg->stat_cumulative) {
|
||||
worker_stats_clear(worker);
|
||||
if(!worker->env.cfg->stat_cumulative) {
|
||||
server_stats_init(&worker->stats, worker->env.cfg);
|
||||
mesh_stats_clear(worker->env.mesh);
|
||||
worker->back->unwanted_replies = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s, int reset)
|
||||
struct stats_info* s)
|
||||
{
|
||||
uint8_t *reply = NULL;
|
||||
uint32_t len = 0;
|
||||
if(worker == who) {
|
||||
/* just fill it in */
|
||||
server_stats_compile(worker, s, reset);
|
||||
server_stats_compile(worker, s);
|
||||
return;
|
||||
}
|
||||
/* communicate over tube */
|
||||
verbose(VERB_ALGO, "write stats cmd");
|
||||
if(reset)
|
||||
worker_send_cmd(who, worker_cmd_stats);
|
||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||
worker_send_cmd(who, worker_cmd_stats);
|
||||
verbose(VERB_ALGO, "wait for stats reply");
|
||||
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
|
||||
fatal_exit("failed to read stats over cmd channel");
|
||||
@@ -215,10 +173,10 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
free(reply);
|
||||
}
|
||||
|
||||
void server_stats_reply(struct worker* worker, int reset)
|
||||
void server_stats_reply(struct worker* worker)
|
||||
{
|
||||
struct stats_info s;
|
||||
server_stats_compile(worker, &s, reset);
|
||||
server_stats_compile(worker, &s);
|
||||
verbose(VERB_ALGO, "write stats replymsg");
|
||||
if(!tube_write_msg(worker->daemon->workers[0]->cmd,
|
||||
(uint8_t*)&s, sizeof(s), 0))
|
||||
@@ -228,18 +186,8 @@ void server_stats_reply(struct worker* worker, int reset)
|
||||
void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
{
|
||||
total->svr.num_queries += a->svr.num_queries;
|
||||
total->svr.num_queries_ip_ratelimited += a->svr.num_queries_ip_ratelimited;
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
total->svr.num_queries_prefetch += a->svr.num_queries_prefetch;
|
||||
total->svr.sum_query_list_size += a->svr.sum_query_list_size;
|
||||
#ifdef USE_DNSCRYPT
|
||||
total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted;
|
||||
total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert;
|
||||
total->svr.num_query_dnscrypt_cleartext += \
|
||||
a->svr.num_query_dnscrypt_cleartext;
|
||||
total->svr.num_query_dnscrypt_crypted_malformed += \
|
||||
a->svr.num_query_dnscrypt_crypted_malformed;
|
||||
#endif
|
||||
/* the max size reached is upped to higher of both */
|
||||
if(a->svr.max_query_list_size > total->svr.max_query_list_size)
|
||||
total->svr.max_query_list_size = a->svr.max_query_list_size;
|
||||
@@ -249,7 +197,6 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.qtype_big += a->svr.qtype_big;
|
||||
total->svr.qclass_big += a->svr.qclass_big;
|
||||
total->svr.qtcp += a->svr.qtcp;
|
||||
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
|
||||
total->svr.qipv6 += a->svr.qipv6;
|
||||
total->svr.qbit_QR += a->svr.qbit_QR;
|
||||
total->svr.qbit_AA += a->svr.qbit_AA;
|
||||
@@ -262,13 +209,11 @@ void server_stats_add(struct stats_info* total, struct stats_info* a)
|
||||
total->svr.qEDNS += a->svr.qEDNS;
|
||||
total->svr.qEDNS_DO += a->svr.qEDNS_DO;
|
||||
total->svr.ans_rcode_nodata += a->svr.ans_rcode_nodata;
|
||||
total->svr.zero_ttl_responses += a->svr.zero_ttl_responses;
|
||||
total->svr.ans_secure += a->svr.ans_secure;
|
||||
total->svr.ans_bogus += a->svr.ans_bogus;
|
||||
total->svr.rrset_bogus += a->svr.rrset_bogus;
|
||||
total->svr.unwanted_replies += a->svr.unwanted_replies;
|
||||
total->svr.unwanted_queries += a->svr.unwanted_queries;
|
||||
total->svr.tcp_accept_usage += a->svr.tcp_accept_usage;
|
||||
for(i=0; i<STATS_QTYPE_NUM; i++)
|
||||
total->svr.qtype[i] += a->svr.qtype[i];
|
||||
for(i=0; i<STATS_QCLASS_NUM; i++)
|
||||
@@ -297,14 +242,14 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
uint16_t qtype, uint16_t qclass, struct edns_data* edns,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
uint16_t flags = sldns_buffer_read_u16_at(c->buffer, 2);
|
||||
uint16_t flags = ldns_buffer_read_u16_at(c->buffer, 2);
|
||||
if(qtype < STATS_QTYPE_NUM)
|
||||
stats->qtype[qtype]++;
|
||||
else stats->qtype_big++;
|
||||
if(qclass < STATS_QCLASS_NUM)
|
||||
stats->qclass[qclass]++;
|
||||
else stats->qclass_big++;
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
|
||||
stats->qopcode[ LDNS_OPCODE_WIRE(ldns_buffer_begin(c->buffer)) ]++;
|
||||
if(c->type != comm_udp)
|
||||
stats->qtcp++;
|
||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
||||
@@ -332,12 +277,12 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
}
|
||||
}
|
||||
|
||||
void server_stats_insrcode(struct server_stats* stats, sldns_buffer* buf)
|
||||
void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf)
|
||||
{
|
||||
if(stats->extended && sldns_buffer_limit(buf) != 0) {
|
||||
int r = (int)LDNS_RCODE_WIRE( sldns_buffer_begin(buf) );
|
||||
if(stats->extended && ldns_buffer_limit(buf) != 0) {
|
||||
int r = (int)LDNS_RCODE_WIRE( ldns_buffer_begin(buf) );
|
||||
stats->ans_rcode[r] ++;
|
||||
if(r == 0 && LDNS_ANCOUNT( sldns_buffer_begin(buf) ) == 0)
|
||||
if(r == 0 && LDNS_ANCOUNT( ldns_buffer_begin(buf) ) == 0)
|
||||
stats->ans_rcode_nodata ++;
|
||||
}
|
||||
}
|
||||
|
||||
+15
-54
@@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,13 +43,11 @@
|
||||
#ifndef DAEMON_STATS_H
|
||||
#define DAEMON_STATS_H
|
||||
#include "util/timehist.h"
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
struct worker;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
struct edns_data;
|
||||
struct sldns_buffer;
|
||||
|
||||
/** number of qtype that is stored for in array */
|
||||
#define STATS_QTYPE_NUM 256
|
||||
@@ -64,12 +62,8 @@ struct sldns_buffer;
|
||||
struct server_stats {
|
||||
/** number of queries from clients received. */
|
||||
size_t num_queries;
|
||||
/** number of queries that have been dropped/ratelimited by ip. */
|
||||
size_t num_queries_ip_ratelimited;
|
||||
/** number of queries that had a cache-miss. */
|
||||
size_t num_queries_missed_cache;
|
||||
/** number of prefetch queries - cachehits with prefetch */
|
||||
size_t num_queries_prefetch;
|
||||
|
||||
/**
|
||||
* Sum of the querylistsize of the worker for
|
||||
@@ -94,8 +88,6 @@ struct server_stats {
|
||||
size_t qopcode[STATS_OPCODE_NUM];
|
||||
/** number of queries over TCP */
|
||||
size_t qtcp;
|
||||
/** number of outgoing queries over TCP */
|
||||
size_t qtcp_outgoing;
|
||||
/** number of queries over IPv6 */
|
||||
size_t qipv6;
|
||||
/** number of queries with QR bit */
|
||||
@@ -132,34 +124,12 @@ struct server_stats {
|
||||
size_t unwanted_replies;
|
||||
/** unwanted traffic received on client-facing ports */
|
||||
size_t unwanted_queries;
|
||||
/** usage of tcp accept list */
|
||||
size_t tcp_accept_usage;
|
||||
/** answers served from expired cache */
|
||||
size_t zero_ttl_responses;
|
||||
|
||||
/** histogram data exported to array
|
||||
* if the array is the same size, no data is lost, and
|
||||
* if all histograms are same size (is so by default) then
|
||||
* adding up works well. */
|
||||
size_t hist[NUM_BUCKETS_HIST];
|
||||
|
||||
/** number of message cache entries */
|
||||
size_t msg_cache_count;
|
||||
/** number of rrset cache entries */
|
||||
size_t rrset_cache_count;
|
||||
/** number of infra cache entries */
|
||||
size_t infra_cache_count;
|
||||
/** number of key cache entries */
|
||||
size_t key_cache_count;
|
||||
#ifdef USE_DNSCRYPT
|
||||
/** number of queries that used dnscrypt */
|
||||
size_t num_query_dnscrypt_crypted;
|
||||
/** number of queries that queried dnscrypt certificates */
|
||||
size_t num_query_dnscrypt_cert;
|
||||
/** number of queries in clear text and not asking for the certificates */
|
||||
size_t num_query_dnscrypt_cleartext;
|
||||
/** number of malformed encrypted queries */
|
||||
size_t num_query_dnscrypt_crypted_malformed;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -196,9 +166,6 @@ void server_stats_init(struct server_stats* stats, struct config_file* cfg);
|
||||
/** add query if it missed the cache */
|
||||
void server_stats_querymiss(struct server_stats* stats, struct worker* worker);
|
||||
|
||||
/** add query if was cached and also resulted in a prefetch */
|
||||
void server_stats_prefetch(struct server_stats* stats, struct worker* worker);
|
||||
|
||||
/** display the stats to the log */
|
||||
void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
int threadnum);
|
||||
@@ -208,29 +175,23 @@ void server_stats_log(struct server_stats* stats, struct worker* worker,
|
||||
* @param worker: the worker that is executing (the first worker).
|
||||
* @param who: on who to get the statistics info.
|
||||
* @param s: the stats block to fill in.
|
||||
* @param reset: if stats can be reset.
|
||||
*/
|
||||
void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
struct stats_info* s, int reset);
|
||||
struct stats_info* s);
|
||||
|
||||
/**
|
||||
* Compile stats into structure for this thread worker.
|
||||
* Also clears the statistics counters (if that is set by config file).
|
||||
* @param worker: the worker to compile stats for, also the executing worker.
|
||||
* @param s: stats block.
|
||||
* @param reset: if true, depending on config stats are reset.
|
||||
* if false, statistics are not reset.
|
||||
*/
|
||||
void server_stats_compile(struct worker* worker, struct stats_info* s,
|
||||
int reset);
|
||||
void server_stats_compile(struct worker* worker, struct stats_info* s);
|
||||
|
||||
/**
|
||||
* Send stats over comm tube in reply to query cmd
|
||||
* @param worker: this worker.
|
||||
* @param reset: if true, depending on config stats are reset.
|
||||
* if false, statistics are not reset.
|
||||
*/
|
||||
void server_stats_reply(struct worker* worker, int reset);
|
||||
void server_stats_reply(struct worker* worker);
|
||||
|
||||
/**
|
||||
* Addup stat blocks.
|
||||
@@ -257,6 +218,6 @@ void server_stats_insquery(struct server_stats* stats, struct comm_point* c,
|
||||
* @param stats: the stats
|
||||
* @param buf: buffer with rcode. If buffer is length0: not counted.
|
||||
*/
|
||||
void server_stats_insrcode(struct server_stats* stats, struct sldns_buffer* buf);
|
||||
void server_stats_insrcode(struct server_stats* stats, ldns_buffer* buf);
|
||||
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
||||
+112
-246
@@ -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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -41,60 +41,42 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include "util/log.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/ub_event.h"
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <openssl/crypto.h>
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifdef HAVE_GRP_H
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#ifndef S_SPLINT_S
|
||||
/* splint chokes on this system header file */
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#endif /* S_SPLINT_S */
|
||||
#ifdef HAVE_LOGIN_CAP_H
|
||||
#include <login_cap.h>
|
||||
|
||||
#ifdef USE_MINI_EVENT
|
||||
# ifdef USE_WINSOCK
|
||||
# include "util/winsock_event.h"
|
||||
# else
|
||||
# include "util/mini_event.h"
|
||||
# endif
|
||||
#else
|
||||
# include <event.h>
|
||||
#endif
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
# include "winrc/win_svc.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NSS
|
||||
/* nss3 */
|
||||
# include "nss.h"
|
||||
#endif
|
||||
/** global debug value to keep track of heap memory allocation */
|
||||
void* unbound_start_brk = 0;
|
||||
|
||||
/** print usage. */
|
||||
static void usage(void)
|
||||
static void usage()
|
||||
{
|
||||
const char** m;
|
||||
const char *evnm="event", *evsys="", *evmethod="";
|
||||
time_t t;
|
||||
struct timeval now;
|
||||
struct ub_event_base* base;
|
||||
printf("usage: unbound [options]\n");
|
||||
printf(" start unbound daemon DNS resolver.\n");
|
||||
printf("-h this help\n");
|
||||
@@ -102,50 +84,18 @@ static void usage(void)
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
#ifdef UB_ON_WINDOWS
|
||||
printf("-w opt windows option: \n");
|
||||
printf(" install, remove - manage the services entry\n");
|
||||
printf(" service - used to start from services control panel\n");
|
||||
#endif
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
base = ub_default_event_base(0,&t,&now);
|
||||
ub_get_event_sys(base, &evnm, &evsys, &evmethod);
|
||||
printf("linked libs: %s %s (it uses %s), %s\n",
|
||||
evnm, evsys, evmethod,
|
||||
#ifdef HAVE_SSL
|
||||
# ifdef SSLEAY_VERSION
|
||||
SSLeay_version(SSLEAY_VERSION)
|
||||
# else
|
||||
OpenSSL_version(OPENSSL_VERSION)
|
||||
# endif
|
||||
#elif defined(HAVE_NSS)
|
||||
NSS_GetVersion()
|
||||
#elif defined(HAVE_NETTLE)
|
||||
"nettle"
|
||||
#endif
|
||||
);
|
||||
printf("linked modules:");
|
||||
for(m = module_list_avail(); *m; m++)
|
||||
printf(" %s", *m);
|
||||
printf("\n");
|
||||
printf("libevent %s, libldns %s, %s\n",
|
||||
event_get_version(), ldns_version(),
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
ub_event_base_free(base);
|
||||
}
|
||||
|
||||
#ifndef unbound_testbound
|
||||
int replay_var_compare(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** check file descriptor count */
|
||||
static void
|
||||
checkrlimits(struct config_file* cfg)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
#ifdef HAVE_GETRLIMIT
|
||||
/* list has number of ports to listen to, ifs number addresses */
|
||||
int list = ((cfg->do_udp?1:0) + (cfg->do_tcp?1 +
|
||||
@@ -164,41 +114,12 @@ checkrlimits(struct config_file* cfg)
|
||||
#if !defined(HAVE_PTHREAD) && !defined(HAVE_SOLARIS_THREADS)
|
||||
int numthread = 1; /* it forks */
|
||||
#else
|
||||
int numthread = (cfg->num_threads?cfg->num_threads:1);
|
||||
int numthread = cfg->num_threads;
|
||||
#endif
|
||||
size_t total = numthread * perthread + misc;
|
||||
size_t avail;
|
||||
struct rlimit rlim;
|
||||
|
||||
if(total > 1024 &&
|
||||
strncmp(ub_event_get_version(), "mini-event", 10) == 0) {
|
||||
log_warn("too many file descriptors requested. The builtin"
|
||||
"mini-event cannot handle more than 1024. Config "
|
||||
"for less fds or compile with libevent");
|
||||
if(numthread*perthread_noudp+15 > 1024)
|
||||
fatal_exit("too much tcp. not enough fds.");
|
||||
cfg->outgoing_num_ports = (int)((1024
|
||||
- numthread*perthread_noudp
|
||||
- 10 /* safety margin */) /numthread);
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
total = 1024;
|
||||
}
|
||||
if(perthread > 64 &&
|
||||
strncmp(ub_event_get_version(), "winsock-event", 13) == 0) {
|
||||
log_err("too many file descriptors requested. The winsock"
|
||||
" event handler cannot handle more than 64 per "
|
||||
" thread. Config for less fds");
|
||||
if(perthread_noudp+2 > 64)
|
||||
fatal_exit("too much tcp. not enough fds.");
|
||||
cfg->outgoing_num_ports = (int)((64
|
||||
- perthread_noudp
|
||||
- 2/* safety margin */));
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
total = numthread*(perthread_noudp+
|
||||
(size_t)cfg->outgoing_num_ports)+misc;
|
||||
}
|
||||
if(getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("getrlimit: %s", strerror(errno));
|
||||
return;
|
||||
@@ -209,10 +130,8 @@ checkrlimits(struct config_file* cfg)
|
||||
avail = (size_t)rlim.rlim_cur;
|
||||
rlim.rlim_cur = (rlim_t)(total + 10);
|
||||
rlim.rlim_max = (rlim_t)(total + 10);
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
if(setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
|
||||
log_warn("setrlimit: %s", strerror(errno));
|
||||
#endif
|
||||
log_warn("cannot increase max open fds from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
/* check that calculation below does not underflow,
|
||||
@@ -224,52 +143,60 @@ checkrlimits(struct config_file* cfg)
|
||||
- 10 /* safety margin */) /numthread);
|
||||
log_warn("continuing with less udp ports: %u",
|
||||
cfg->outgoing_num_ports);
|
||||
log_warn("increase ulimit or decrease threads, "
|
||||
"ports in config to remove this warning");
|
||||
log_warn("increase ulimit or decrease threads, ports in config to remove this warning");
|
||||
return;
|
||||
#ifdef HAVE_SETRLIMIT
|
||||
}
|
||||
#endif
|
||||
verbose(VERB_ALGO, "increased limit(open files) from %u to %u",
|
||||
log_warn("increased limit(open files) from %u to %u",
|
||||
(unsigned)avail, (unsigned)total+10);
|
||||
}
|
||||
if(total > 1024 &&
|
||||
strncmp(event_get_version(), "mini-event", 10) == 0) {
|
||||
log_err("too many file descriptors requested. The builtin"
|
||||
"mini-event cannot handle more than 1024. Config "
|
||||
"for less fds or compile with libevent");
|
||||
fatal_exit("configuration needs too many file descriptors");
|
||||
}
|
||||
if(perthread > 64 &&
|
||||
strncmp(event_get_version(), "winsock-event", 13) == 0) {
|
||||
log_err("too many file descriptors requested. The winsock"
|
||||
" event handler cannot handle more than 64 per "
|
||||
" thread. Config for less fds or compile with "
|
||||
" libevent");
|
||||
fatal_exit("configuration needs too many file descriptors");
|
||||
}
|
||||
#else
|
||||
(void)cfg;
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
#endif /* S_SPLINT_S */
|
||||
}
|
||||
|
||||
/** set default logfile identity based on value from argv[0] at startup **/
|
||||
static void
|
||||
log_ident_set_fromdefault(struct config_file* cfg,
|
||||
const char *log_default_identity)
|
||||
{
|
||||
if(cfg->log_identity == NULL || cfg->log_identity[0] == 0)
|
||||
log_ident_set(log_default_identity);
|
||||
else
|
||||
log_ident_set(cfg->log_identity);
|
||||
}
|
||||
|
||||
/** set verbosity, check rlimits, cache settings */
|
||||
static void
|
||||
apply_settings(struct daemon* daemon, struct config_file* cfg,
|
||||
int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
int cmdline_verbose)
|
||||
{
|
||||
/* apply if they have changed */
|
||||
daemon->cfg = cfg;
|
||||
verbosity = cmdline_verbose + cfg->verbosity;
|
||||
if (debug_mode > 1) {
|
||||
cfg->use_syslog = 0;
|
||||
free(cfg->logfile);
|
||||
cfg->logfile = NULL;
|
||||
config_apply(cfg);
|
||||
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,
|
||||
msgreply_sizefunc, query_info_compare,
|
||||
query_entry_delete, reply_info_delete, NULL);
|
||||
if(!daemon->env->msg_cache) {
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
}
|
||||
}
|
||||
daemon_apply_cfg(daemon, cfg);
|
||||
if((daemon->env->rrset_cache = rrset_cache_adjust(
|
||||
daemon->env->rrset_cache, cfg, &daemon->superalloc)) == 0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
if((daemon->env->infra_cache = infra_adjust(daemon->env->infra_cache,
|
||||
cfg))==0)
|
||||
fatal_exit("malloc failure updating config settings");
|
||||
checkrlimits(cfg);
|
||||
|
||||
if (cfg->use_systemd && cfg->do_daemonize) {
|
||||
log_warn("use-systemd and do-daemonize should not be enabled at the same time");
|
||||
}
|
||||
|
||||
log_ident_set_fromdefault(cfg, log_default_identity);
|
||||
}
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
@@ -364,12 +291,7 @@ checkoldpid(char* pidfile, int inchroot)
|
||||
static void
|
||||
detach(void)
|
||||
{
|
||||
#if defined(HAVE_DAEMON) && !defined(DEPRECATED_DAEMON)
|
||||
/* use POSIX daemon(3) function */
|
||||
if(daemon(1, 0) != 0)
|
||||
fatal_exit("daemon failed: %s", strerror(errno));
|
||||
#else /* no HAVE_DAEMON */
|
||||
#ifdef HAVE_FORK
|
||||
#ifdef HAVE_WORKING_FORK
|
||||
int fd;
|
||||
/* Take off... */
|
||||
switch (fork()) {
|
||||
@@ -393,8 +315,7 @@ detach(void)
|
||||
if (fd > 2)
|
||||
(void)close(fd);
|
||||
}
|
||||
#endif /* HAVE_FORK */
|
||||
#endif /* HAVE_DAEMON */
|
||||
#endif /* HAVE_WORKING_FORK */
|
||||
}
|
||||
|
||||
/** daemonize, drop user priviliges and chroot if needed */
|
||||
@@ -402,21 +323,23 @@ static void
|
||||
perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
const char** cfgfile)
|
||||
{
|
||||
#ifdef HAVE_KILL
|
||||
int pidinchroot;
|
||||
#endif
|
||||
#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]) {
|
||||
struct passwd *pwd;
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
/* endpwent below, in case we need pwd for setusercontext */
|
||||
uid = pwd->pw_uid;
|
||||
gid = pwd->pw_gid;
|
||||
endpwent();
|
||||
}
|
||||
#endif
|
||||
#ifdef UB_ON_WINDOWS
|
||||
w_config_adjust_directory(cfg);
|
||||
#endif
|
||||
|
||||
/* init syslog (as root) if needed, before daemonize, otherwise
|
||||
* a fork error could not be printed since daemonize closed stderr.*/
|
||||
@@ -429,26 +352,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* So, using a logfile, the user does not see errors unless -d is
|
||||
* given to unbound on the commandline. */
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
if(!(daemon->listen_sslctx = listen_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, NULL)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_KILL
|
||||
/* true if pidfile is inside chrootdir, or nochroot */
|
||||
pidinchroot = !(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(cfg->pidfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir))==0);
|
||||
|
||||
/* check old pid file before forking */
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
/* calculate position of pidfile */
|
||||
@@ -458,7 +362,12 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
cfg, 1);
|
||||
if(!daemon->pidfile)
|
||||
fatal_exit("pidfile alloc: out of memory");
|
||||
checkoldpid(daemon->pidfile, pidinchroot);
|
||||
checkoldpid(daemon->pidfile,
|
||||
/* true if pidfile is inside chrootdir, or nochroot */
|
||||
!(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(daemon->pidfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir))==0));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -471,35 +380,24 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
#ifdef HAVE_KILL
|
||||
if(cfg->pidfile && cfg->pidfile[0]) {
|
||||
writepid(daemon->pidfile, getpid());
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
|
||||
pidinchroot) {
|
||||
# ifdef HAVE_CHOWN
|
||||
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
|
||||
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
if(!(cfg->chrootdir && cfg->chrootdir[0]) ||
|
||||
(cfg->chrootdir && cfg->chrootdir[0] &&
|
||||
strncmp(daemon->pidfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir))==0)) {
|
||||
/* delete of pidfile could potentially work,
|
||||
* chown to get permissions */
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(chown(daemon->pidfile, uid, gid) == -1) {
|
||||
fatal_exit("cannot chown %u.%u %s: %s",
|
||||
(unsigned)uid, (unsigned)gid,
|
||||
daemon->pidfile, strerror(errno));
|
||||
}
|
||||
# endif /* HAVE_CHOWN */
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif /* HAVE_KILL */
|
||||
|
||||
/* Set user context */
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
|
||||
#ifdef HAVE_SETUSERCONTEXT
|
||||
/* setusercontext does initgroups, setuid, setgid, and
|
||||
* also resource limits from login config, but we
|
||||
* still call setresuid, setresgid to be sure to set all uid*/
|
||||
if(setusercontext(NULL, pwd, cfg_uid, (unsigned)
|
||||
LOGIN_SETALL & ~LOGIN_SETUSER & ~LOGIN_SETGROUP) != 0)
|
||||
log_warn("unable to setusercontext %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
#endif /* HAVE_SETUSERCONTEXT */
|
||||
}
|
||||
#endif /* HAVE_GETPWNAM */
|
||||
#endif
|
||||
|
||||
/* box into the chroot */
|
||||
#ifdef HAVE_CHROOT
|
||||
@@ -512,9 +410,6 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
if(chroot(cfg->chrootdir))
|
||||
fatal_exit("unable to chroot to %s: %s",
|
||||
cfg->chrootdir, strerror(errno));
|
||||
if(chdir("/"))
|
||||
fatal_exit("unable to chdir to / in chroot %s: %s",
|
||||
cfg->chrootdir, strerror(errno));
|
||||
verbose(VERB_QUERY, "chroot to %s", cfg->chrootdir);
|
||||
if(strncmp(*cfgfile, cfg->chrootdir,
|
||||
strlen(cfg->chrootdir)) == 0)
|
||||
@@ -555,38 +450,29 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
|
||||
/* drop permissions after chroot, getpwnam, pidfile, syslog done*/
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
|
||||
# ifdef HAVE_INITGROUPS
|
||||
if(initgroups(cfg->username, cfg_gid) != 0)
|
||||
log_warn("unable to initgroups %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
# endif /* HAVE_INITGROUPS */
|
||||
# ifdef HAVE_ENDPWENT
|
||||
endpwent();
|
||||
# endif
|
||||
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
#ifdef HAVE_SETRESGID
|
||||
if(setresgid(cfg_gid,cfg_gid,cfg_gid) != 0)
|
||||
if(setresgid(gid,gid,gid) != 0)
|
||||
#elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID)
|
||||
if(setregid(cfg_gid,cfg_gid) != 0)
|
||||
if(setregid(gid,gid) != 0)
|
||||
#else /* use setgid */
|
||||
if(setgid(cfg_gid) != 0)
|
||||
if(setgid(gid) != 0)
|
||||
#endif /* HAVE_SETRESGID */
|
||||
fatal_exit("unable to set group id of %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
#ifdef HAVE_SETRESUID
|
||||
if(setresuid(cfg_uid,cfg_uid,cfg_uid) != 0)
|
||||
if(setresuid(uid,uid,uid) != 0)
|
||||
#elif defined(HAVE_SETREUID) && !defined(DARWIN_BROKEN_SETREUID)
|
||||
if(setreuid(cfg_uid,cfg_uid) != 0)
|
||||
if(setreuid(uid,uid) != 0)
|
||||
#else /* use setuid */
|
||||
if(setuid(cfg_uid) != 0)
|
||||
if(setuid(uid) != 0)
|
||||
#endif /* HAVE_SETRESUID */
|
||||
fatal_exit("unable to set user id of %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
verbose(VERB_QUERY, "drop user privileges, run as %s",
|
||||
cfg->username);
|
||||
}
|
||||
#endif /* HAVE_GETPWNAM */
|
||||
#endif
|
||||
/* file logging inited after chroot,chdir,setuid is done so that
|
||||
* it would succeed on SIGHUP as well */
|
||||
if(!cfg->use_syslog)
|
||||
@@ -599,10 +485,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
* @param cmdline_verbose: verbosity resulting from commandline -v.
|
||||
* These increase verbosity as specified in the config file.
|
||||
* @param debug_mode: if set, do not daemonize.
|
||||
* @param log_default_identity: Default identity to report in logs
|
||||
*/
|
||||
static void
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char* log_default_identity)
|
||||
run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode)
|
||||
{
|
||||
struct config_file* cfg = NULL;
|
||||
struct daemon* daemon = NULL;
|
||||
@@ -624,15 +509,13 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode, const char*
|
||||
cfgfile);
|
||||
log_warn("Continuing with default config settings");
|
||||
}
|
||||
apply_settings(daemon, cfg, cmdline_verbose, debug_mode, log_default_identity);
|
||||
if(!done_setup)
|
||||
config_lookup_uid(cfg);
|
||||
apply_settings(daemon, cfg, cmdline_verbose);
|
||||
|
||||
/* prepare */
|
||||
if(!daemon_open_shared_ports(daemon))
|
||||
fatal_exit("could not open ports");
|
||||
if(!done_setup) {
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
perform_setup(daemon, cfg, debug_mode, &cfgfile);
|
||||
done_setup = 1;
|
||||
} else {
|
||||
/* reopen log after HUP to facilitate log rotation */
|
||||
@@ -678,35 +561,27 @@ main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
const char* cfgfile = CONFIGFILE;
|
||||
const char* winopt = NULL;
|
||||
const char* log_ident_default;
|
||||
int cmdline_verbose = 0;
|
||||
int debug_mode = 0;
|
||||
#ifdef UB_ON_WINDOWS
|
||||
int cmdline_cfg = 0;
|
||||
|
||||
#ifdef HAVE_SBRK
|
||||
/* take debug snapshot of heap */
|
||||
unbound_start_brk = sbrk(0);
|
||||
#endif
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_default = strrchr(argv[0],'/')?strrchr(argv[0],'/')+1:argv[0];
|
||||
log_ident_set(log_ident_default);
|
||||
/* parse the options */
|
||||
while( (c=getopt(argc, argv, "c:dhvw:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "c:dhv")) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
cfgfile = optarg;
|
||||
#ifdef UB_ON_WINDOWS
|
||||
cmdline_cfg = 1;
|
||||
#endif
|
||||
break;
|
||||
case 'v':
|
||||
cmdline_verbose++;
|
||||
cmdline_verbose ++;
|
||||
verbosity++;
|
||||
break;
|
||||
case 'd':
|
||||
debug_mode++;
|
||||
break;
|
||||
case 'w':
|
||||
winopt = optarg;
|
||||
debug_mode = 1;
|
||||
break;
|
||||
case '?':
|
||||
case 'h':
|
||||
@@ -718,21 +593,12 @@ main(int argc, char* argv[])
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if(winopt) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_command_option(winopt, cfgfile, cmdline_verbose,
|
||||
cmdline_cfg);
|
||||
#else
|
||||
fatal_exit("option not supported");
|
||||
#endif
|
||||
}
|
||||
|
||||
if(argc != 0) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode, log_ident_default);
|
||||
run_daemon(cfgfile, cmdline_verbose, debug_mode);
|
||||
log_init(NULL, 0, NULL); /* close logfile */
|
||||
return 0;
|
||||
}
|
||||
|
||||
+353
-968
File diff suppressed because it is too large
Load Diff
+84
-28
@@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -43,7 +43,7 @@
|
||||
#ifndef DAEMON_WORKER_H
|
||||
#define DAEMON_WORKER_H
|
||||
|
||||
#include "libunbound/worker.h"
|
||||
#include "config.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/locks.h"
|
||||
#include "util/alloc.h"
|
||||
@@ -51,7 +51,6 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "util/module.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
struct listen_dnsport;
|
||||
struct outside_network;
|
||||
struct config_file;
|
||||
@@ -61,7 +60,6 @@ struct ub_randstate;
|
||||
struct regional;
|
||||
struct tube;
|
||||
struct daemon_remote;
|
||||
struct query_info;
|
||||
|
||||
/** worker commands */
|
||||
enum worker_commands {
|
||||
@@ -69,8 +67,6 @@ enum worker_commands {
|
||||
worker_cmd_quit,
|
||||
/** obtain statistics */
|
||||
worker_cmd_stats,
|
||||
/** obtain statistics without statsclear */
|
||||
worker_cmd_stats_noreset,
|
||||
/** execute remote control command */
|
||||
worker_cmd_remote
|
||||
};
|
||||
@@ -85,7 +81,7 @@ struct worker {
|
||||
/** global shared daemon structure */
|
||||
struct daemon* daemon;
|
||||
/** thread id */
|
||||
ub_thread_type thr_id;
|
||||
ub_thread_t thr_id;
|
||||
/** pipe, for commands for this worker */
|
||||
struct tube* cmd;
|
||||
/** the event base this worker works with */
|
||||
@@ -104,10 +100,11 @@ struct worker {
|
||||
struct comm_point* cmd_com;
|
||||
/** timer for statistics */
|
||||
struct comm_timer* stat_timer;
|
||||
/** ratelimit for errors, time value */
|
||||
time_t err_limit_time;
|
||||
/** ratelimit for errors, packet count */
|
||||
unsigned int err_limit_count;
|
||||
/** remote control state (for first thread only) */
|
||||
struct daemon_remote* rc;
|
||||
|
||||
/** number of requests that can be handled by this worker */
|
||||
size_t request_size;
|
||||
|
||||
/** random() table for this worker. */
|
||||
struct ub_randstate* rndstate;
|
||||
@@ -122,11 +119,6 @@ struct worker {
|
||||
|
||||
/** module environment passed to modules, changed for this thread */
|
||||
struct module_env env;
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
/** dnstap environment, changed for this thread */
|
||||
struct dt_env dtenv;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -170,9 +162,73 @@ void worker_delete(struct worker* worker);
|
||||
void worker_send_cmd(struct worker* worker, enum worker_commands cmd);
|
||||
|
||||
/**
|
||||
* Init worker stats - includes server_stats_init, outside network and mesh.
|
||||
* @param worker: the worker to init
|
||||
* Worker signal handler function. User argument is the worker itself.
|
||||
* @param sig: signal number.
|
||||
* @param arg: the worker (main worker) that handles signals.
|
||||
*/
|
||||
void worker_stats_clear(struct worker* worker);
|
||||
void worker_sighandler(int sig, void* arg);
|
||||
|
||||
/**
|
||||
* Worker service routine to send udp messages for modules.
|
||||
* @param pkt: packet to send.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param timeout: seconds to wait until timeout.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @param use_tcp: true to use TCP, false for UDP.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
int worker_send_packet(ldns_buffer* pkt, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int timeout, struct module_qstate* q, int use_tcp);
|
||||
|
||||
/**
|
||||
* Worker service routine to send serviced queries to authoritative servers.
|
||||
* @param qname: query name. (host order)
|
||||
* @param qnamelen: length in bytes of qname, including trailing 0.
|
||||
* @param qtype: query type. (host order)
|
||||
* @param qclass: query class. (host order)
|
||||
* @param flags: host order flags word, with opcode and CD bit.
|
||||
* @param dnssec: if set, EDNS record will have DO bit set.
|
||||
* @param addr: where to.
|
||||
* @param addrlen: length of addr.
|
||||
* @param q: wich query state to reactivate upon return.
|
||||
* @return: false on failure (memory or socket related). no query was
|
||||
* sent.
|
||||
*/
|
||||
struct outbound_entry* worker_send_query(uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint16_t flags, int dnssec,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||
struct module_qstate* q);
|
||||
|
||||
/**
|
||||
* process control messages from the main thread. Frees the control
|
||||
* command message.
|
||||
* @param tube: tube control message came on.
|
||||
* @param msg: message contents. Is freed.
|
||||
* @param len: length of message.
|
||||
* @param error: if error (NETEVENT_*) happened.
|
||||
* @param arg: user argument
|
||||
*/
|
||||
void worker_handle_control_cmd(struct tube* tube, uint8_t* msg, size_t len,
|
||||
int error, void* arg);
|
||||
|
||||
/** handles callbacks from listening event interface */
|
||||
int worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply* repinfo);
|
||||
|
||||
/** process incoming replies from the network */
|
||||
int worker_handle_reply(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply* reply_info);
|
||||
|
||||
/** process incoming serviced query replies from the network */
|
||||
int worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply* reply_info);
|
||||
|
||||
/** cleanup the cache to remove all rrset IDs from it, arg is worker */
|
||||
void worker_alloc_cleanup(void* arg);
|
||||
|
||||
/** statistics timer callback handler */
|
||||
void worker_stat_timer_cb(void* arg);
|
||||
|
||||
#endif /* DAEMON_WORKER_H */
|
||||
|
||||
-854
@@ -1,854 +0,0 @@
|
||||
/*
|
||||
* dns64/dns64.c - DNS64 module
|
||||
*
|
||||
* Copyright (c) 2009, Viagénie. 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 Viagénie nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* This file contains a module that performs DNS64 query processing.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dns64/dns64.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
* STATIC CONSTANTS *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* This is the default DNS64 prefix that is used whent he dns64 module is listed
|
||||
* in module-config but when the dns64-prefix variable is not present.
|
||||
*/
|
||||
static const char DEFAULT_DNS64_PREFIX[] = "64:ff9b::/96";
|
||||
|
||||
/**
|
||||
* Maximum length of a domain name in a PTR query in the .in-addr.arpa tree.
|
||||
*/
|
||||
#define MAX_PTR_QNAME_IPV4 30
|
||||
|
||||
/**
|
||||
* Per-query module-specific state. This is usually a dynamically-allocated
|
||||
* structure, but in our case we only need to store one variable describing the
|
||||
* state the query is in. So we repurpose the minfo pointer by storing an
|
||||
* integer in there.
|
||||
*/
|
||||
enum dns64_qstate {
|
||||
DNS64_INTERNAL_QUERY, /**< Internally-generated query, no DNS64
|
||||
processing. */
|
||||
DNS64_NEW_QUERY, /**< Query for which we're the first module in
|
||||
line. */
|
||||
DNS64_SUBQUERY_FINISHED /**< Query for which we generated a sub-query, and
|
||||
for which this sub-query is finished. */
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
* STRUCTURES *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* This structure contains module configuration information. One instance of
|
||||
* this structure exists per instance of the module. Normally there is only one
|
||||
* instance of the module.
|
||||
*/
|
||||
struct dns64_env {
|
||||
/**
|
||||
* DNS64 prefix address. We're using a full sockaddr instead of just an
|
||||
* in6_addr because we can reuse Unbound's generic string parsing functions.
|
||||
* It will always contain a sockaddr_in6, and only the sin6_addr member will
|
||||
* ever be used.
|
||||
*/
|
||||
struct sockaddr_storage prefix_addr;
|
||||
|
||||
/**
|
||||
* This is always sizeof(sockaddr_in6).
|
||||
*/
|
||||
socklen_t prefix_addrlen;
|
||||
|
||||
/**
|
||||
* This is the CIDR length of the prefix. It needs to be between 0 and 96.
|
||||
*/
|
||||
int prefix_net;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
* UTILITY FUNCTIONS *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Generic macro for swapping two variables.
|
||||
*
|
||||
* \param t Type of the variables. (e.g. int)
|
||||
* \param a First variable.
|
||||
* \param b Second variable.
|
||||
*
|
||||
* \warning Do not attempt something foolish such as swap(int,a++,b++)!
|
||||
*/
|
||||
#define swap(t,a,b) do {t x = a; a = b; b = x;} while(0)
|
||||
|
||||
/**
|
||||
* Reverses a string.
|
||||
*
|
||||
* \param begin Points to the first character of the string.
|
||||
* \param end Points one past the last character of the string.
|
||||
*/
|
||||
static void
|
||||
reverse(char* begin, char* end)
|
||||
{
|
||||
while ( begin < --end ) {
|
||||
swap(char, *begin, *end);
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an unsigned integer to a string. The point of this function is that
|
||||
* of being faster than sprintf().
|
||||
*
|
||||
* \param n The number to be converted.
|
||||
* \param s The result will be written here. Must be large enough, be careful!
|
||||
*
|
||||
* \return The number of characters written.
|
||||
*/
|
||||
static int
|
||||
uitoa(unsigned n, char* s)
|
||||
{
|
||||
char* ss = s;
|
||||
do {
|
||||
*ss++ = '0' + n % 10;
|
||||
} while (n /= 10);
|
||||
reverse(s, ss);
|
||||
return ss - s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract an IPv4 address embedded in the IPv6 address \a ipv6 at offset \a
|
||||
* offset (in bits). Note that bits are not necessarily aligned on bytes so we
|
||||
* need to be careful.
|
||||
*
|
||||
* \param ipv6 IPv6 address represented as a 128-bit array in big-endian
|
||||
* order.
|
||||
* \param offset Index of the MSB of the IPv4 address embedded in the IPv6
|
||||
* address.
|
||||
*/
|
||||
static uint32_t
|
||||
extract_ipv4(const uint8_t ipv6[16], const int offset)
|
||||
{
|
||||
uint32_t ipv4 = (uint32_t)ipv6[offset/8+0] << (24 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+1] << (16 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+2] << ( 8 + (offset%8))
|
||||
| (uint32_t)ipv6[offset/8+3] << ( 0 + (offset%8));
|
||||
if (offset/8+4 < 16)
|
||||
ipv4 |= (uint32_t)ipv6[offset/8+4] >> (8 - offset%8);
|
||||
return ipv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the PTR query name corresponding to an IPv4 address. For example,
|
||||
* given the number 3,464,175,361, this will build the string
|
||||
* "\03206\03123\0231\011\07in-addr\04arpa".
|
||||
*
|
||||
* \param ipv4 IPv4 address represented as an unsigned 32-bit number.
|
||||
* \param ptr The result will be written here. Must be large enough, be
|
||||
* careful!
|
||||
*
|
||||
* \return The number of characters written.
|
||||
*/
|
||||
static size_t
|
||||
ipv4_to_ptr(uint32_t ipv4, char ptr[MAX_PTR_QNAME_IPV4])
|
||||
{
|
||||
static const char IPV4_PTR_SUFFIX[] = "\07in-addr\04arpa";
|
||||
int i;
|
||||
char* c = ptr;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
*c = uitoa((unsigned int)(ipv4 % 256), c + 1);
|
||||
c += *c + 1;
|
||||
ipv4 /= 256;
|
||||
}
|
||||
|
||||
memmove(c, IPV4_PTR_SUFFIX, sizeof(IPV4_PTR_SUFFIX));
|
||||
|
||||
return c + sizeof(IPV4_PTR_SUFFIX) - ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an IPv6-related domain name string from a PTR query into an IPv6
|
||||
* address represented as a 128-bit array.
|
||||
*
|
||||
* \param ptr The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa")
|
||||
* \param ipv6 The result will be written here, in network byte order.
|
||||
*
|
||||
* \return 1 on success, 0 on failure.
|
||||
*/
|
||||
static int
|
||||
ptr_to_ipv6(const char* ptr, uint8_t ipv6[16])
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int x;
|
||||
|
||||
if (ptr[i++] != 1)
|
||||
return 0;
|
||||
|
||||
if (ptr[i] >= '0' && ptr[i] <= '9') {
|
||||
x = ptr[i] - '0';
|
||||
} else if (ptr[i] >= 'a' && ptr[i] <= 'f') {
|
||||
x = ptr[i] - 'a' + 10;
|
||||
} else if (ptr[i] >= 'A' && ptr[i] <= 'F') {
|
||||
x = ptr[i] - 'A' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ipv6[15-i/4] |= x << (2 * ((i-1) % 4));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
|
||||
*
|
||||
* \param prefix_addr DNS64 prefix address.
|
||||
* \param prefix_net CIDR length of the DNS64 prefix. Must be between 0 and 96.
|
||||
* \param a IPv4 address.
|
||||
* \param aaaa IPv6 address. The result will be written here.
|
||||
*/
|
||||
static void
|
||||
synthesize_aaaa(const uint8_t prefix_addr[16], int prefix_net,
|
||||
const uint8_t a[4], uint8_t aaaa[16])
|
||||
{
|
||||
memcpy(aaaa, prefix_addr, 16);
|
||||
aaaa[prefix_net/8+0] |= a[0] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+1] |= a[0] << (8-prefix_net%8);
|
||||
aaaa[prefix_net/8+1] |= a[1] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+2] |= a[1] << (8-prefix_net%8);
|
||||
aaaa[prefix_net/8+2] |= a[2] >> (0+prefix_net%8);
|
||||
aaaa[prefix_net/8+3] |= a[2] << (8-prefix_net%8);
|
||||
aaaa[prefix_net/8+3] |= a[3] >> (0+prefix_net%8);
|
||||
if (prefix_net/8+4 < 16) /* <-- my beautiful symmetry is destroyed! */
|
||||
aaaa[prefix_net/8+4] |= a[3] << (8-prefix_net%8);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* *
|
||||
* DNS64 MODULE FUNCTIONS *
|
||||
* *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* This function applies the configuration found in the parsed configuration
|
||||
* file \a cfg to this instance of the dns64 module. Currently only the DNS64
|
||||
* prefix (a.k.a. Pref64) is configurable.
|
||||
*
|
||||
* \param dns64_env Module-specific global parameters.
|
||||
* \param cfg Parsed configuration file.
|
||||
*/
|
||||
static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
|
||||
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
|
||||
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (dns64_env->prefix_net < 0 || dns64_env->prefix_net > 96) {
|
||||
log_err("dns64-prefix length it not between 0 and 96: %s",
|
||||
cfg->dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this instance of the dns64 module.
|
||||
*
|
||||
* \param env Global state of all module instances.
|
||||
* \param id This instance's ID number.
|
||||
*/
|
||||
int
|
||||
dns64_init(struct module_env* env, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env =
|
||||
(struct dns64_env*)calloc(1, sizeof(struct dns64_env));
|
||||
if (!dns64_env) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
env->modinfo[id] = (void*)dns64_env;
|
||||
if (!dns64_apply_cfg(dns64_env, env->cfg)) {
|
||||
log_err("dns64: could not apply configuration settings.");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deinitializes this instance of the dns64 module.
|
||||
*
|
||||
* \param env Global state of all module instances.
|
||||
* \param id This instance's ID number.
|
||||
*/
|
||||
void
|
||||
dns64_deinit(struct module_env* env, int id)
|
||||
{
|
||||
if (!env)
|
||||
return;
|
||||
free(env->modinfo[id]);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle PTR queries for IPv6 addresses. If the address belongs to the DNS64
|
||||
* prefix, we must do a PTR query for the corresponding IPv4 address instead.
|
||||
*
|
||||
* \param qstate Query state structure.
|
||||
* \param id This module instance's ID number.
|
||||
*
|
||||
* \return The new state of the query.
|
||||
*/
|
||||
static enum module_ext_state
|
||||
handle_ipv6_ptr(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env = (struct dns64_env*)qstate->env->modinfo[id];
|
||||
struct module_qstate* subq = NULL;
|
||||
struct query_info qinfo;
|
||||
struct sockaddr_in6 sin6;
|
||||
|
||||
/* Convert the PTR query string to an IPv6 address. */
|
||||
memset(&sin6, 0, sizeof(sin6));
|
||||
sin6.sin6_family = AF_INET6;
|
||||
if (!ptr_to_ipv6((char*)qstate->qinfo.qname, sin6.sin6_addr.s6_addr))
|
||||
return module_wait_module; /* Let other module handle this. */
|
||||
|
||||
/*
|
||||
* If this IPv6 address is not part of our DNS64 prefix, then we don't need
|
||||
* to do anything. Let another module handle the query.
|
||||
*/
|
||||
if (addr_in_common((struct sockaddr_storage*)&sin6, 128,
|
||||
&dns64_env->prefix_addr, dns64_env->prefix_net,
|
||||
(socklen_t)sizeof(sin6)) != dns64_env->prefix_net)
|
||||
return module_wait_module;
|
||||
|
||||
verbose(VERB_ALGO, "dns64: rewrite PTR record");
|
||||
|
||||
/*
|
||||
* Create a new PTR query info for the domain name corresponding to the IPv4
|
||||
* address corresponding to the IPv6 address corresponding to the original
|
||||
* PTR query domain name.
|
||||
*/
|
||||
qinfo = qstate->qinfo;
|
||||
if (!(qinfo.qname = regional_alloc(qstate->region, MAX_PTR_QNAME_IPV4)))
|
||||
return module_error;
|
||||
qinfo.qname_len = ipv4_to_ptr(extract_ipv4(sin6.sin6_addr.s6_addr,
|
||||
dns64_env->prefix_net), (char*)qinfo.qname);
|
||||
|
||||
/* Create the new sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0,
|
||||
&subq))
|
||||
return module_error;
|
||||
if (subq) {
|
||||
subq->curmod = id;
|
||||
subq->ext_state[id] = module_state_initial;
|
||||
subq->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
return module_wait_subquery;
|
||||
}
|
||||
|
||||
static enum module_ext_state
|
||||
generate_type_A_query(struct module_qstate* qstate, int id)
|
||||
{
|
||||
struct module_qstate* subq = NULL;
|
||||
struct query_info qinfo;
|
||||
|
||||
verbose(VERB_ALGO, "dns64: query A record");
|
||||
|
||||
/* Create a new query info. */
|
||||
qinfo = qstate->qinfo;
|
||||
qinfo.qtype = LDNS_RR_TYPE_A;
|
||||
|
||||
/* Start the sub-query. */
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0,
|
||||
0, &subq))
|
||||
{
|
||||
verbose(VERB_ALGO, "dns64: sub-query creation failed");
|
||||
return module_error;
|
||||
}
|
||||
if (subq) {
|
||||
subq->curmod = id;
|
||||
subq->ext_state[id] = module_state_initial;
|
||||
subq->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
return module_wait_subquery;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "pass" event for a query. This event is received when a new query
|
||||
* is received by this module. The query may have been generated internally by
|
||||
* another module, in which case we don't want to do any special processing
|
||||
* (this is an interesting discussion topic), or it may be brand new, e.g.
|
||||
* received over a socket, in which case we do want to apply DNS64 processing.
|
||||
*
|
||||
* \param qstate A structure representing the state of the query that has just
|
||||
* received the "pass" event.
|
||||
* \param id This module's instance ID.
|
||||
*
|
||||
* \return The new state of the query.
|
||||
*/
|
||||
static enum module_ext_state
|
||||
handle_event_pass(struct module_qstate* qstate, int id)
|
||||
{
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_PTR
|
||||
&& qstate->qinfo.qname_len == 74
|
||||
&& !strcmp((char*)&qstate->qinfo.qname[64], "\03ip6\04arpa"))
|
||||
/* Handle PTR queries for IPv6 addresses. */
|
||||
return handle_ipv6_ptr(qstate, id);
|
||||
|
||||
if (qstate->env->cfg->dns64_synthall &&
|
||||
(uintptr_t)qstate->minfo[id] == DNS64_NEW_QUERY
|
||||
&& qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA)
|
||||
return generate_type_A_query(qstate, id);
|
||||
|
||||
/* We are finished when our sub-query is finished. */
|
||||
if ((uintptr_t)qstate->minfo[id] == DNS64_SUBQUERY_FINISHED)
|
||||
return module_finished;
|
||||
|
||||
/* Otherwise, pass request to next module. */
|
||||
verbose(VERB_ALGO, "dns64: pass to next module");
|
||||
return module_wait_module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the "done" event for a query. We need to analyze the response and
|
||||
* maybe issue a new sub-query for the A record.
|
||||
*
|
||||
* \param qstate A structure representing the state of the query that has just
|
||||
* received the "pass" event.
|
||||
* \param id This module's instance ID.
|
||||
*
|
||||
* \return The new state of the query.
|
||||
*/
|
||||
static enum module_ext_state
|
||||
handle_event_moddone(struct module_qstate* qstate, int id)
|
||||
{
|
||||
/*
|
||||
* In many cases we have nothing special to do. From most to least common:
|
||||
*
|
||||
* - An internal query.
|
||||
* - A query for a record type other than AAAA.
|
||||
* - CD FLAG was set on querier
|
||||
* - An AAAA query for which an error was returned.(qstate.return_rcode)
|
||||
* -> treated as servfail thus synthesize (sec 5.1.3 6147), thus
|
||||
* synthesize in (sec 5.1.2 of RFC6147).
|
||||
* - A successful AAAA query with an answer.
|
||||
*/
|
||||
if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY
|
||||
|| qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA
|
||||
|| (qstate->query_flags & BIT_CD)
|
||||
|| (qstate->return_msg &&
|
||||
qstate->return_msg->rep &&
|
||||
reply_find_answer_rrset(&qstate->qinfo,
|
||||
qstate->return_msg->rep)))
|
||||
return module_finished;
|
||||
|
||||
/* So, this is a AAAA noerror/nodata answer */
|
||||
return generate_type_A_query(qstate, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the module's main() function. It gets called each time a query
|
||||
* receives an event which we may need to handle. We respond by updating the
|
||||
* state of the query.
|
||||
*
|
||||
* \param qstate Structure containing the state of the query.
|
||||
* \param event Event that has just been received.
|
||||
* \param id This module's instance ID.
|
||||
* \param outbound State of a DNS query on an authoritative server. We never do
|
||||
* our own queries ourselves (other modules do it for us), so
|
||||
* this is unused.
|
||||
*/
|
||||
void
|
||||
dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound)
|
||||
{
|
||||
(void)outbound;
|
||||
verbose(VERB_QUERY, "dns64[module %d] operate: extstate:%s event:%s",
|
||||
id, strextstate(qstate->ext_state[id]),
|
||||
strmodulevent(event));
|
||||
log_query_info(VERB_QUERY, "dns64 operate: query", &qstate->qinfo);
|
||||
|
||||
switch(event) {
|
||||
case module_event_new:
|
||||
/* Tag this query as being new and fall through. */
|
||||
qstate->minfo[id] = (void*)DNS64_NEW_QUERY;
|
||||
case module_event_pass:
|
||||
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
||||
break;
|
||||
case module_event_moddone:
|
||||
qstate->ext_state[id] = handle_event_moddone(qstate, id);
|
||||
break;
|
||||
default:
|
||||
qstate->ext_state[id] = module_finished;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dns64_synth_aaaa_data(const struct ub_packed_rrset_key* fk,
|
||||
const struct packed_rrset_data* fd,
|
||||
struct ub_packed_rrset_key *dk,
|
||||
struct packed_rrset_data **dd_out, struct regional *region,
|
||||
struct dns64_env* dns64_env )
|
||||
{
|
||||
struct packed_rrset_data *dd;
|
||||
size_t i;
|
||||
/*
|
||||
* Create synthesized AAAA RR set data. We need to allocated extra memory
|
||||
* for the RRs themselves. Each RR has a length, TTL, pointer to wireformat
|
||||
* data, 2 bytes of data length, and 16 bytes of IPv6 address.
|
||||
*/
|
||||
if(fd->count > RR_COUNT_MAX) {
|
||||
*dd_out = NULL;
|
||||
return; /* integer overflow protection in alloc */
|
||||
}
|
||||
if (!(dd = *dd_out = regional_alloc(region,
|
||||
sizeof(struct packed_rrset_data)
|
||||
+ fd->count * (sizeof(size_t) + sizeof(time_t) +
|
||||
sizeof(uint8_t*) + 2 + 16)))) {
|
||||
log_err("out of memory");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy attributes from A RR set. */
|
||||
dd->ttl = fd->ttl;
|
||||
dd->count = fd->count;
|
||||
dd->rrsig_count = 0;
|
||||
dd->trust = fd->trust;
|
||||
dd->security = fd->security;
|
||||
|
||||
/*
|
||||
* Synthesize AAAA records. Adjust pointers in structure.
|
||||
*/
|
||||
dd->rr_len =
|
||||
(size_t*)((uint8_t*)dd + sizeof(struct packed_rrset_data));
|
||||
dd->rr_data = (uint8_t**)&dd->rr_len[dd->count];
|
||||
dd->rr_ttl = (time_t*)&dd->rr_data[dd->count];
|
||||
for(i = 0; i < fd->count; ++i) {
|
||||
if (fd->rr_len[i] != 6 || fd->rr_data[i][0] != 0
|
||||
|| fd->rr_data[i][1] != 4) {
|
||||
*dd_out = NULL;
|
||||
return;
|
||||
}
|
||||
dd->rr_len[i] = 18;
|
||||
dd->rr_data[i] =
|
||||
(uint8_t*)&dd->rr_ttl[dd->count] + 18*i;
|
||||
dd->rr_data[i][0] = 0;
|
||||
dd->rr_data[i][1] = 16;
|
||||
synthesize_aaaa(
|
||||
((struct sockaddr_in6*)&dns64_env->prefix_addr)->sin6_addr.s6_addr,
|
||||
dns64_env->prefix_net, &fd->rr_data[i][2],
|
||||
&dd->rr_data[i][2] );
|
||||
dd->rr_ttl[i] = fd->rr_ttl[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Create synthesized AAAA RR set key. This is mostly just bookkeeping,
|
||||
* nothing interesting here.
|
||||
*/
|
||||
if(!dk) {
|
||||
log_err("no key");
|
||||
*dd_out = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
dk->rk.dname = (uint8_t*)regional_alloc_init(region,
|
||||
fk->rk.dname, fk->rk.dname_len);
|
||||
|
||||
if(!dk->rk.dname) {
|
||||
log_err("out of memory");
|
||||
*dd_out = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
dk->rk.type = htons(LDNS_RR_TYPE_AAAA);
|
||||
memset(&dk->entry, 0, sizeof(dk->entry));
|
||||
dk->entry.key = dk;
|
||||
dk->entry.hash = rrset_key_hash(&dk->rk);
|
||||
dk->entry.data = dd;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize an AAAA RR set from an A sub-query's answer and add it to the
|
||||
* original empty response.
|
||||
*
|
||||
* \param id This module's instance ID.
|
||||
* \param super Original AAAA query.
|
||||
* \param qstate A query.
|
||||
*/
|
||||
static void
|
||||
dns64_adjust_a(int id, struct module_qstate* super, struct module_qstate* qstate)
|
||||
{
|
||||
struct dns64_env* dns64_env = (struct dns64_env*)super->env->modinfo[id];
|
||||
struct reply_info *rep, *cp;
|
||||
size_t i, s;
|
||||
struct packed_rrset_data* fd, *dd;
|
||||
struct ub_packed_rrset_key* fk, *dk;
|
||||
|
||||
verbose(VERB_ALGO, "converting A answers to AAAA answers");
|
||||
|
||||
log_assert(super->region);
|
||||
log_assert(qstate->return_msg);
|
||||
log_assert(qstate->return_msg->rep);
|
||||
|
||||
/* If dns64-synthall is enabled, return_msg is not initialized */
|
||||
if(!super->return_msg) {
|
||||
super->return_msg = (struct dns_msg*)regional_alloc(
|
||||
super->region, sizeof(struct dns_msg));
|
||||
if(!super->return_msg)
|
||||
return;
|
||||
memset(super->return_msg, 0, sizeof(*super->return_msg));
|
||||
super->return_msg->qinfo = super->qinfo;
|
||||
}
|
||||
|
||||
rep = qstate->return_msg->rep;
|
||||
|
||||
/*
|
||||
* Build the actual reply.
|
||||
*/
|
||||
cp = construct_reply_info_base(super->region, rep->flags, rep->qdcount,
|
||||
rep->ttl, rep->prefetch_ttl, rep->an_numrrsets, rep->ns_numrrsets,
|
||||
rep->ar_numrrsets, rep->rrset_count, rep->security);
|
||||
if(!cp)
|
||||
return;
|
||||
|
||||
/* allocate ub_key structures special or not */
|
||||
if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy everything and replace A by AAAA */
|
||||
for(i=0; i<cp->rrset_count; i++) {
|
||||
fk = rep->rrsets[i];
|
||||
dk = cp->rrsets[i];
|
||||
fd = (struct packed_rrset_data*)fk->entry.data;
|
||||
dk->rk = fk->rk;
|
||||
dk->id = fk->id;
|
||||
|
||||
if(i<rep->an_numrrsets && fk->rk.type == htons(LDNS_RR_TYPE_A)) {
|
||||
/* also sets dk->entry.hash */
|
||||
dns64_synth_aaaa_data(fk, fd, dk, &dd, super->region, dns64_env);
|
||||
if(!dd)
|
||||
return;
|
||||
/* Delete negative AAAA record from cache stored by
|
||||
* the iterator module */
|
||||
rrset_cache_remove(super->env->rrset_cache, dk->rk.dname,
|
||||
dk->rk.dname_len, LDNS_RR_TYPE_AAAA,
|
||||
LDNS_RR_CLASS_IN, 0);
|
||||
} else {
|
||||
dk->entry.hash = fk->entry.hash;
|
||||
dk->rk.dname = (uint8_t*)regional_alloc_init(super->region,
|
||||
fk->rk.dname, fk->rk.dname_len);
|
||||
|
||||
if(!dk->rk.dname)
|
||||
return;
|
||||
|
||||
s = packed_rrset_sizeof(fd);
|
||||
dd = (struct packed_rrset_data*)regional_alloc_init(
|
||||
super->region, fd, s);
|
||||
|
||||
if(!dd)
|
||||
return;
|
||||
}
|
||||
|
||||
packed_rrset_ptr_fixup(dd);
|
||||
dk->entry.data = (void*)dd;
|
||||
}
|
||||
|
||||
/* Commit changes. */
|
||||
super->return_msg->rep = cp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a response for the original IPv6 PTR query based on an IPv4 PTR
|
||||
* sub-query's response.
|
||||
*
|
||||
* \param qstate IPv4 PTR sub-query.
|
||||
* \param super Original IPv6 PTR query.
|
||||
*/
|
||||
static void
|
||||
dns64_adjust_ptr(struct module_qstate* qstate, struct module_qstate* super)
|
||||
{
|
||||
struct ub_packed_rrset_key* answer;
|
||||
|
||||
verbose(VERB_ALGO, "adjusting PTR reply");
|
||||
|
||||
/* Copy the sub-query's reply to the parent. */
|
||||
if (!(super->return_msg = (struct dns_msg*)regional_alloc(super->region,
|
||||
sizeof(struct dns_msg))))
|
||||
return;
|
||||
super->return_msg->qinfo = super->qinfo;
|
||||
super->return_msg->rep = reply_info_copy(qstate->return_msg->rep, NULL,
|
||||
super->region);
|
||||
|
||||
/*
|
||||
* Adjust the domain name of the answer RR set so that it matches the
|
||||
* initial query's domain name.
|
||||
*/
|
||||
answer = reply_find_answer_rrset(&qstate->qinfo, super->return_msg->rep);
|
||||
log_assert(answer);
|
||||
answer->rk.dname = super->qinfo.qname;
|
||||
answer->rk.dname_len = super->qinfo.qname_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called when a sub-query finishes to inform the parent query.
|
||||
*
|
||||
* We issue two kinds of sub-queries: PTR and A.
|
||||
*
|
||||
* \param qstate State of the sub-query.
|
||||
* \param id This module's instance ID.
|
||||
* \param super State of the super-query.
|
||||
*/
|
||||
void
|
||||
dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super)
|
||||
{
|
||||
log_query_info(VERB_ALGO, "dns64: inform_super, sub is",
|
||||
&qstate->qinfo);
|
||||
log_query_info(VERB_ALGO, "super is", &super->qinfo);
|
||||
|
||||
/*
|
||||
* Signal that the sub-query is finished, no matter whether we are
|
||||
* successful or not. This lets the state machine terminate.
|
||||
*/
|
||||
super->minfo[id] = (void*)DNS64_SUBQUERY_FINISHED;
|
||||
|
||||
/* If there is no successful answer, we're done. */
|
||||
if (qstate->return_rcode != LDNS_RCODE_NOERROR
|
||||
|| !qstate->return_msg
|
||||
|| !qstate->return_msg->rep
|
||||
|| !reply_find_answer_rrset(&qstate->qinfo,
|
||||
qstate->return_msg->rep))
|
||||
return;
|
||||
|
||||
/* Generate a response suitable for the original query. */
|
||||
if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
|
||||
dns64_adjust_a(id, super, qstate);
|
||||
} else {
|
||||
log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR);
|
||||
dns64_adjust_ptr(qstate, super);
|
||||
}
|
||||
|
||||
/* Store the generated response in cache. */
|
||||
if (!super->no_cache_store &&
|
||||
!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep,
|
||||
0, 0, 0, NULL, super->query_flags))
|
||||
log_err("out of memory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear module-specific data from query state. Since we do not allocate memory,
|
||||
* it's just a matter of setting a pointer to NULL.
|
||||
*
|
||||
* \param qstate Query state.
|
||||
* \param id This module's instance ID.
|
||||
*/
|
||||
void
|
||||
dns64_clear(struct module_qstate* qstate, int id)
|
||||
{
|
||||
qstate->minfo[id] = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of global memory that this module uses, not including
|
||||
* per-query data.
|
||||
*
|
||||
* \param env Module environment.
|
||||
* \param id This module's instance ID.
|
||||
*/
|
||||
size_t
|
||||
dns64_get_mem(struct module_env* env, int id)
|
||||
{
|
||||
struct dns64_env* dns64_env = (struct dns64_env*)env->modinfo[id];
|
||||
if (!dns64_env)
|
||||
return 0;
|
||||
return sizeof(*dns64_env);
|
||||
}
|
||||
|
||||
/**
|
||||
* The dns64 function block.
|
||||
*/
|
||||
static struct module_func_block dns64_block = {
|
||||
"dns64",
|
||||
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
|
||||
&dns64_clear, &dns64_get_mem
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for returning the above function block.
|
||||
*/
|
||||
struct module_func_block *
|
||||
dns64_get_funcblock(void)
|
||||
{
|
||||
return &dns64_block;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* dns64/dns64.h - DNS64 module
|
||||
*
|
||||
* Copyright (c) 2009, Viagénie. 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 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 contains a module that performs DNS64 query processing.
|
||||
*/
|
||||
|
||||
#ifndef DNS64_DNS64_H
|
||||
#define DNS64_DNS64_H
|
||||
#include "util/module.h"
|
||||
|
||||
/**
|
||||
* Get the dns64 function block.
|
||||
* @return: function block with function pointers to dns64 methods.
|
||||
*/
|
||||
struct module_func_block *dns64_get_funcblock(void);
|
||||
|
||||
/** dns64 init */
|
||||
int dns64_init(struct module_env* env, int id);
|
||||
|
||||
/** dns64 deinit */
|
||||
void dns64_deinit(struct module_env* env, int id);
|
||||
|
||||
/** dns64 operate on a query */
|
||||
void dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
struct outbound_entry* outbound);
|
||||
|
||||
void dns64_inform_super(struct module_qstate* qstate, int id,
|
||||
struct module_qstate* super);
|
||||
|
||||
/** dns64 cleanup query state */
|
||||
void dns64_clear(struct module_qstate* qstate, int id);
|
||||
|
||||
/** dns64 alloc size routine */
|
||||
size_t dns64_get_mem(struct module_env* env, int id);
|
||||
|
||||
#endif /* DNS64_DNS64_H */
|
||||
@@ -1,32 +0,0 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_CERT_H
|
||||
#define UNBOUND_DNSCRYPT_CERT_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* certificate type for dnscrypt for use in other header files
|
||||
*/
|
||||
|
||||
#include <sodium.h>
|
||||
#define CERT_MAGIC_CERT "DNSC"
|
||||
#define CERT_MAJOR_VERSION 1
|
||||
#define CERT_MINOR_VERSION 0
|
||||
#define CERT_OLD_MAGIC_HEADER "7PYqwfzt"
|
||||
|
||||
#define CERT_FILE_EXPIRE_DAYS 365
|
||||
|
||||
struct SignedCert {
|
||||
uint8_t magic_cert[4];
|
||||
uint8_t version_major[2];
|
||||
uint8_t version_minor[2];
|
||||
|
||||
// Signed Content
|
||||
uint8_t server_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t magic_query[8];
|
||||
uint8_t serial[4];
|
||||
uint8_t ts_begin[4];
|
||||
uint8_t ts_end[4];
|
||||
uint8_t end[64];
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,531 +0,0 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include "dnscrypt/cert.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/**
|
||||
* \file
|
||||
* dnscrypt functions for encrypting DNS packets.
|
||||
*/
|
||||
|
||||
#define DNSCRYPT_QUERY_BOX_OFFSET \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES)
|
||||
|
||||
// 8 bytes: magic header (CERT_MAGIC_HEADER)
|
||||
// 12 bytes: the client's nonce
|
||||
// 12 bytes: server nonce extension
|
||||
// 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
|
||||
|
||||
#define DNSCRYPT_REPLY_BOX_OFFSET \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES + crypto_box_HALF_NONCEBYTES)
|
||||
|
||||
/**
|
||||
* Decrypt a query using the keypair that was found using dnsc_find_keypair.
|
||||
* The client nonce will be extracted from the encrypted query and stored in
|
||||
* client_nonce, a shared secret will be computed and stored in nmkey and the
|
||||
* buffer will be decrypted inplace.
|
||||
* \param[in] keypair the keypair that matches this encrypted query.
|
||||
* \param[in] client_nonce where the client nonce will be stored.
|
||||
* \param[in] nmkey where the shared secret key will be written.
|
||||
* \param[in] buffer the encrypted buffer.
|
||||
* \return 0 on success.
|
||||
*/
|
||||
static int
|
||||
dnscrypt_server_uncurve(const KeyPair *keypair,
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES],
|
||||
struct sldns_buffer* buffer)
|
||||
{
|
||||
size_t len = sldns_buffer_limit(buffer);
|
||||
uint8_t *const buf = sldns_buffer_begin(buffer);
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
struct dnscrypt_query_header *query_header;
|
||||
|
||||
if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
query_header = (struct dnscrypt_query_header *)buf;
|
||||
memcpy(nmkey, query_header->publickey, crypto_box_PUBLICKEYBYTES);
|
||||
if (crypto_box_beforenm(nmkey, nmkey, keypair->crypt_secretkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(nonce, query_header->nonce, crypto_box_HALF_NONCEBYTES);
|
||||
memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
|
||||
|
||||
sldns_buffer_set_at(buffer,
|
||||
DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
0, crypto_box_BOXZEROBYTES);
|
||||
|
||||
if (crypto_box_open_afternm
|
||||
(buf + DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
buf + DNSCRYPT_QUERY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
len - DNSCRYPT_QUERY_BOX_OFFSET + crypto_box_BOXZEROBYTES, nonce,
|
||||
nmkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (*sldns_buffer_at(buffer, --len) == 0)
|
||||
;
|
||||
|
||||
if (*sldns_buffer_at(buffer, len) != 0x80) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
|
||||
memmove(sldns_buffer_begin(buffer),
|
||||
sldns_buffer_at(buffer, DNSCRYPT_QUERY_HEADER_SIZE),
|
||||
len - DNSCRYPT_QUERY_HEADER_SIZE);
|
||||
|
||||
sldns_buffer_set_position(buffer, 0);
|
||||
sldns_buffer_set_limit(buffer, len - DNSCRYPT_QUERY_HEADER_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add random padding to a buffer, according to a client nonce.
|
||||
* The length has to depend on the query in order to avoid reply attacks.
|
||||
*
|
||||
* @param buf a buffer
|
||||
* @param len the initial size of the buffer
|
||||
* @param max_len the maximum size
|
||||
* @param nonce a nonce, made of the client nonce repeated twice
|
||||
* @param secretkey
|
||||
* @return the new size, after padding
|
||||
*/
|
||||
size_t
|
||||
dnscrypt_pad(uint8_t *buf, const size_t len, const size_t max_len,
|
||||
const uint8_t *nonce, const uint8_t *secretkey)
|
||||
{
|
||||
uint8_t *buf_padding_area = buf + len;
|
||||
size_t padded_len;
|
||||
uint32_t rnd;
|
||||
|
||||
// no padding
|
||||
if (max_len < len + DNSCRYPT_MIN_PAD_LEN)
|
||||
return len;
|
||||
|
||||
assert(nonce[crypto_box_HALF_NONCEBYTES] == nonce[0]);
|
||||
|
||||
crypto_stream((unsigned char *)&rnd, (unsigned long long)sizeof(rnd), nonce,
|
||||
secretkey);
|
||||
padded_len =
|
||||
len + DNSCRYPT_MIN_PAD_LEN + rnd % (max_len - len -
|
||||
DNSCRYPT_MIN_PAD_LEN + 1);
|
||||
padded_len += DNSCRYPT_BLOCK_SIZE - padded_len % DNSCRYPT_BLOCK_SIZE;
|
||||
if (padded_len > max_len)
|
||||
padded_len = max_len;
|
||||
|
||||
memset(buf_padding_area, 0, padded_len - len);
|
||||
*buf_padding_area = 0x80;
|
||||
|
||||
return padded_len;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
dnscrypt_hrtime(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
uint64_t ts = (uint64_t)0U;
|
||||
int ret;
|
||||
|
||||
ret = gettimeofday(&tv, NULL);
|
||||
if (ret == 0) {
|
||||
ts = (uint64_t)tv.tv_sec * 1000000U + (uint64_t)tv.tv_usec;
|
||||
} else {
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
}
|
||||
return ts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the server nonce part to once.
|
||||
* The nonce is made half of client nonce and the seconf half of the server
|
||||
* nonce, both of them of size crypto_box_HALF_NONCEBYTES.
|
||||
* \param[in] nonce: a uint8_t* of size crypto_box_NONCEBYTES
|
||||
*/
|
||||
static void
|
||||
add_server_nonce(uint8_t *nonce)
|
||||
{
|
||||
uint64_t ts;
|
||||
uint64_t tsn;
|
||||
uint32_t suffix;
|
||||
ts = dnscrypt_hrtime();
|
||||
// TODO? dnscrypt-wrapper does some logic with context->nonce_ts_last
|
||||
// unclear if we really need it, so skipping it for now.
|
||||
tsn = (ts << 10) | (randombytes_random() & 0x3ff);
|
||||
#if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
tsn =
|
||||
(((uint64_t)htonl((uint32_t)tsn)) << 32) | htonl((uint32_t)(tsn >> 32));
|
||||
#endif
|
||||
memcpy(nonce + crypto_box_HALF_NONCEBYTES, &tsn, 8);
|
||||
suffix = randombytes_random();
|
||||
memcpy(nonce + crypto_box_HALF_NONCEBYTES + 8, &suffix, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a reply using the keypair that was used with the query.
|
||||
* The client nonce will be extracted from the encrypted query and stored in
|
||||
* The buffer will be encrypted inplace.
|
||||
* \param[in] keypair the keypair that matches this encrypted query.
|
||||
* \param[in] client_nonce client nonce used during the query
|
||||
* \param[in] nmkey shared secret key used during the query.
|
||||
* \param[in] buffer the buffer where to encrypt the reply.
|
||||
* \param[in] udp if whether or not it is a UDP query.
|
||||
* \param[in] max_udp_size configured max udp size.
|
||||
* \return 0 on success.
|
||||
*/
|
||||
static int
|
||||
dnscrypt_server_curve(const KeyPair *keypair,
|
||||
uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
|
||||
uint8_t nmkey[crypto_box_BEFORENMBYTES],
|
||||
struct sldns_buffer* buffer,
|
||||
uint8_t udp,
|
||||
size_t max_udp_size)
|
||||
{
|
||||
size_t dns_reply_len = sldns_buffer_limit(buffer);
|
||||
size_t max_len = dns_reply_len + DNSCRYPT_MAX_PADDING + DNSCRYPT_REPLY_HEADER_SIZE;
|
||||
size_t max_reply_size = max_udp_size - 20U - 8U;
|
||||
uint8_t nonce[crypto_box_NONCEBYTES];
|
||||
uint8_t *boxed;
|
||||
uint8_t *const buf = sldns_buffer_begin(buffer);
|
||||
size_t len = sldns_buffer_limit(buffer);
|
||||
|
||||
if(udp){
|
||||
if (max_len > max_reply_size)
|
||||
max_len = max_reply_size;
|
||||
}
|
||||
|
||||
|
||||
memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
|
||||
memcpy(nonce + crypto_box_HALF_NONCEBYTES, client_nonce,
|
||||
crypto_box_HALF_NONCEBYTES);
|
||||
|
||||
boxed = buf + DNSCRYPT_REPLY_BOX_OFFSET;
|
||||
memmove(boxed + crypto_box_MACBYTES, buf, len);
|
||||
len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
|
||||
max_len - DNSCRYPT_REPLY_HEADER_SIZE, nonce,
|
||||
keypair->crypt_secretkey);
|
||||
sldns_buffer_set_at(buffer,
|
||||
DNSCRYPT_REPLY_BOX_OFFSET - crypto_box_BOXZEROBYTES,
|
||||
0, crypto_box_ZEROBYTES);
|
||||
|
||||
// add server nonce extension
|
||||
add_server_nonce(nonce);
|
||||
|
||||
if (crypto_box_afternm
|
||||
(boxed - crypto_box_BOXZEROBYTES, boxed - crypto_box_BOXZEROBYTES,
|
||||
len + crypto_box_ZEROBYTES, nonce, nmkey) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sldns_buffer_write_at(buffer, 0, DNSCRYPT_MAGIC_RESPONSE, DNSCRYPT_MAGIC_HEADER_LEN);
|
||||
sldns_buffer_write_at(buffer, DNSCRYPT_MAGIC_HEADER_LEN, nonce, crypto_box_NONCEBYTES);
|
||||
sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the content of fname into buf.
|
||||
* \param[in] fname name of the file to read.
|
||||
* \param[in] buf the buffer in which to read the content of the file.
|
||||
* \param[in] count number of bytes to read.
|
||||
* \return 0 on success.
|
||||
*/
|
||||
static int
|
||||
dnsc_read_from_file(char *fname, char *buf, size_t count)
|
||||
{
|
||||
int fd;
|
||||
fd = open(fname, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (read(fd, buf, count) != (ssize_t)count) {
|
||||
close(fd);
|
||||
return -2;
|
||||
}
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse certificates files provided by the configuration and load them into
|
||||
* dnsc_env.
|
||||
* \param[in] env the dnsc_env structure to load the certs into.
|
||||
* \param[in] cfg the configuration.
|
||||
* \return the number of certificates loaded.
|
||||
*/
|
||||
static int
|
||||
dnsc_parse_certs(struct dnsc_env *env, struct config_file *cfg)
|
||||
{
|
||||
struct config_strlist *head;
|
||||
size_t signed_cert_id;
|
||||
|
||||
env->signed_certs_count = 0U;
|
||||
for (head = cfg->dnscrypt_provider_cert; head; head = head->next) {
|
||||
env->signed_certs_count++;
|
||||
}
|
||||
env->signed_certs = sodium_allocarray(env->signed_certs_count,
|
||||
sizeof *env->signed_certs);
|
||||
|
||||
signed_cert_id = 0U;
|
||||
for(head = cfg->dnscrypt_provider_cert; head; head = head->next, signed_cert_id++) {
|
||||
if(dnsc_read_from_file(
|
||||
head->str,
|
||||
(char *)(env->signed_certs + signed_cert_id),
|
||||
sizeof(struct SignedCert)) != 0) {
|
||||
fatal_exit("dnsc_parse_certs: failed to load %s: %s", head->str, strerror(errno));
|
||||
}
|
||||
verbose(VERB_OPS, "Loaded cert %s", head->str);
|
||||
}
|
||||
return signed_cert_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to convert a binary key into a printable fingerprint.
|
||||
* \param[in] fingerprint the buffer in which to write the printable key.
|
||||
* \param[in] key the key to convert.
|
||||
*/
|
||||
void
|
||||
dnsc_key_to_fingerprint(char fingerprint[80U], const uint8_t * const key)
|
||||
{
|
||||
const size_t fingerprint_size = 80U;
|
||||
size_t fingerprint_pos = (size_t) 0U;
|
||||
size_t key_pos = (size_t) 0U;
|
||||
|
||||
for (;;) {
|
||||
assert(fingerprint_size > fingerprint_pos);
|
||||
snprintf(&fingerprint[fingerprint_pos],
|
||||
fingerprint_size - fingerprint_pos, "%02X%02X",
|
||||
key[key_pos], key[key_pos + 1U]);
|
||||
key_pos += 2U;
|
||||
if (key_pos >= crypto_box_PUBLICKEYBYTES) {
|
||||
break;
|
||||
}
|
||||
fingerprint[fingerprint_pos + 4U] = ':';
|
||||
fingerprint_pos += 5U;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the keypair matching a DNSCrypt query.
|
||||
* \param[in] dnscenv The DNSCrypt enviroment, which contains the list of keys
|
||||
* supported by the server.
|
||||
* \param[in] buffer The encrypted DNS query.
|
||||
* \return a KeyPair * if we found a key pair matching the query, NULL otherwise.
|
||||
*/
|
||||
static const KeyPair *
|
||||
dnsc_find_keypair(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
|
||||
{
|
||||
const KeyPair *keypairs = dnscenv->keypairs;
|
||||
struct dnscrypt_query_header *dnscrypt_header;
|
||||
size_t i;
|
||||
|
||||
if (sldns_buffer_limit(buffer) < DNSCRYPT_QUERY_HEADER_SIZE) {
|
||||
return NULL;
|
||||
}
|
||||
dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
|
||||
for (i = 0U; i < dnscenv->keypairs_count; i++) {
|
||||
if (memcmp(keypairs[i].crypt_publickey, dnscrypt_header->magic_query,
|
||||
DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
|
||||
return &keypairs[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert local-zone and local-data into configuration.
|
||||
* In order to be able to serve certs over TXT, we can reuse the local-zone and
|
||||
* local-data config option. The zone and qname are infered from the
|
||||
* provider_name and the content of the TXT record from the certificate content.
|
||||
* returns the number of certtificate TXT record that were loaded.
|
||||
* < 0 in case of error.
|
||||
*/
|
||||
static int
|
||||
dnsc_load_local_data(struct dnsc_env* dnscenv, struct config_file *cfg)
|
||||
{
|
||||
size_t i, j;
|
||||
// Insert 'local-zone: "2.dnscrypt-cert.example.com" deny'
|
||||
if(!cfg_str2list_insert(&cfg->local_zones,
|
||||
strdup(dnscenv->provider_name),
|
||||
strdup("deny"))) {
|
||||
log_err("Could not load dnscrypt local-zone: %s deny",
|
||||
dnscenv->provider_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add local data entry of type:
|
||||
// 2.dnscrypt-cert.example.com 86400 IN TXT "DNSC......"
|
||||
for(i=0; i<dnscenv->signed_certs_count; i++) {
|
||||
const char *ttl_class_type = " 86400 IN TXT \"";
|
||||
struct SignedCert *cert = dnscenv->signed_certs + i;
|
||||
uint16_t rrlen = strlen(dnscenv->provider_name) +
|
||||
strlen(ttl_class_type) +
|
||||
4 * sizeof(struct SignedCert) + // worst case scenario
|
||||
1 + // trailing double quote
|
||||
1;
|
||||
char *rr = malloc(rrlen);
|
||||
if(!rr) {
|
||||
log_err("Could not allocate memory");
|
||||
return -2;
|
||||
}
|
||||
snprintf(rr, rrlen - 1, "%s 86400 IN TXT \"", dnscenv->provider_name);
|
||||
for(j=0; j<sizeof(struct SignedCert); j++) {
|
||||
int c = (int)*((const uint8_t *) cert + j);
|
||||
if (isprint(c) && c != '"' && c != '\\') {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "%c", c);
|
||||
} else {
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\\%03d", c);
|
||||
}
|
||||
}
|
||||
snprintf(rr + strlen(rr), rrlen - 1 - strlen(rr), "\"");
|
||||
cfg_strlist_insert(&cfg->local_data, strdup(rr));
|
||||
free(rr);
|
||||
}
|
||||
return dnscenv->signed_certs_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the secret key files from `dnscrypt-secret-key` config and populates
|
||||
* a list of secret/public keys supported by dnscrypt listener.
|
||||
* \param[in] env The dnsc_env structure which will hold the keypairs.
|
||||
* \param[in] cfg The config with the secret key file paths.
|
||||
*/
|
||||
static int
|
||||
dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
|
||||
{
|
||||
struct config_strlist *head;
|
||||
size_t keypair_id;
|
||||
|
||||
env->keypairs_count = 0U;
|
||||
for (head = cfg->dnscrypt_secret_key; head; head = head->next) {
|
||||
env->keypairs_count++;
|
||||
}
|
||||
env->keypairs = sodium_allocarray(env->keypairs_count,
|
||||
sizeof *env->keypairs);
|
||||
|
||||
keypair_id = 0U;
|
||||
for(head = cfg->dnscrypt_secret_key; head; head = head->next, keypair_id++) {
|
||||
char fingerprint[80];
|
||||
if(dnsc_read_from_file(
|
||||
head->str,
|
||||
(char *)(env->keypairs[keypair_id].crypt_secretkey),
|
||||
crypto_box_SECRETKEYBYTES) != 0) {
|
||||
fatal_exit("dnsc_parse_keys: failed to load %s: %s", head->str, strerror(errno));
|
||||
}
|
||||
verbose(VERB_OPS, "Loaded key %s", head->str);
|
||||
if (crypto_scalarmult_base(env->keypairs[keypair_id].crypt_publickey,
|
||||
env->keypairs[keypair_id].crypt_secretkey) != 0) {
|
||||
fatal_exit("dnsc_parse_keys: could not generate public key from %s", head->str);
|
||||
}
|
||||
dnsc_key_to_fingerprint(fingerprint, env->keypairs[keypair_id].crypt_publickey);
|
||||
verbose(VERB_OPS, "Crypt public key fingerprint for %s: %s", head->str, fingerprint);
|
||||
}
|
||||
return keypair_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* #########################################################
|
||||
* ############# Publicly accessible functions #############
|
||||
* #########################################################
|
||||
*/
|
||||
|
||||
int
|
||||
dnsc_handle_curved_request(struct dnsc_env* dnscenv,
|
||||
struct comm_reply* repinfo)
|
||||
{
|
||||
struct comm_point* c = repinfo->c;
|
||||
|
||||
repinfo->is_dnscrypted = 0;
|
||||
if( !c->dnscrypt ) {
|
||||
return 1;
|
||||
}
|
||||
// Attempt to decrypt the query. If it is not crypted, we may still need
|
||||
// to serve the certificate.
|
||||
verbose(VERB_ALGO, "handle request called on DNSCrypt socket");
|
||||
if ((repinfo->keypair = dnsc_find_keypair(dnscenv, c->buffer)) != NULL) {
|
||||
if(dnscrypt_server_uncurve(repinfo->keypair,
|
||||
repinfo->client_nonce,
|
||||
repinfo->nmkey,
|
||||
c->buffer) != 0){
|
||||
verbose(VERB_ALGO, "dnscrypt: Failed to uncurve");
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
repinfo->is_dnscrypted = 1;
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
dnsc_handle_uncurved_request(struct comm_reply *repinfo)
|
||||
{
|
||||
if(!repinfo->c->dnscrypt) {
|
||||
return 1;
|
||||
}
|
||||
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
|
||||
if(!repinfo->is_dnscrypted) {
|
||||
return 1;
|
||||
}
|
||||
if(dnscrypt_server_curve(repinfo->keypair,
|
||||
repinfo->client_nonce,
|
||||
repinfo->nmkey,
|
||||
repinfo->c->dnscrypt_buffer,
|
||||
repinfo->c->type == comm_udp,
|
||||
repinfo->max_udp_size) != 0){
|
||||
verbose(VERB_ALGO, "dnscrypt: Failed to curve cached missed answer");
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
struct dnsc_env *
|
||||
dnsc_create(void)
|
||||
{
|
||||
struct dnsc_env *env;
|
||||
if (sodium_init() == -1) {
|
||||
fatal_exit("dnsc_create: could not initialize libsodium.");
|
||||
}
|
||||
env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
|
||||
return env;
|
||||
}
|
||||
|
||||
int
|
||||
dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
|
||||
{
|
||||
if(dnsc_parse_certs(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: no cert file loaded");
|
||||
}
|
||||
if(dnsc_parse_keys(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: no key file loaded");
|
||||
}
|
||||
randombytes_buf(env->hash_key, sizeof env->hash_key);
|
||||
env->provider_name = cfg->dnscrypt_provider;
|
||||
|
||||
if(dnsc_load_local_data(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: could not load local data");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_H
|
||||
#define UNBOUND_DNSCRYPT_H
|
||||
|
||||
/**
|
||||
* \file
|
||||
* dnscrypt functions for encrypting DNS packets.
|
||||
*/
|
||||
|
||||
#include "dnscrypt/dnscrypt_config.h"
|
||||
#ifdef USE_DNSCRYPT
|
||||
|
||||
#define DNSCRYPT_MAGIC_HEADER_LEN 8U
|
||||
#define DNSCRYPT_MAGIC_RESPONSE "r6fnvWj8"
|
||||
|
||||
#ifndef DNSCRYPT_MAX_PADDING
|
||||
# define DNSCRYPT_MAX_PADDING 256U
|
||||
#endif
|
||||
#ifndef DNSCRYPT_BLOCK_SIZE
|
||||
# define DNSCRYPT_BLOCK_SIZE 64U
|
||||
#endif
|
||||
#ifndef DNSCRYPT_MIN_PAD_LEN
|
||||
# define DNSCRYPT_MIN_PAD_LEN 8U
|
||||
#endif
|
||||
|
||||
#define crypto_box_HALF_NONCEBYTES (crypto_box_NONCEBYTES / 2U)
|
||||
|
||||
#include "config.h"
|
||||
#include "dnscrypt/cert.h"
|
||||
|
||||
#define DNSCRYPT_QUERY_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES + crypto_box_MACBYTES)
|
||||
#define DNSCRYPT_RESPONSE_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_NONCEBYTES + crypto_box_MACBYTES)
|
||||
|
||||
#define DNSCRYPT_REPLY_HEADER_SIZE \
|
||||
(DNSCRYPT_MAGIC_HEADER_LEN + crypto_box_HALF_NONCEBYTES * 2 + crypto_box_MACBYTES)
|
||||
|
||||
struct sldns_buffer;
|
||||
struct config_file;
|
||||
struct comm_reply;
|
||||
|
||||
typedef struct KeyPair_ {
|
||||
uint8_t crypt_publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t crypt_secretkey[crypto_box_SECRETKEYBYTES];
|
||||
} KeyPair;
|
||||
|
||||
struct dnsc_env {
|
||||
struct SignedCert *signed_certs;
|
||||
size_t signed_certs_count;
|
||||
uint8_t provider_publickey[crypto_sign_ed25519_PUBLICKEYBYTES];
|
||||
uint8_t provider_secretkey[crypto_sign_ed25519_SECRETKEYBYTES];
|
||||
KeyPair *keypairs;
|
||||
size_t keypairs_count;
|
||||
uint64_t nonce_ts_last;
|
||||
unsigned char hash_key[crypto_shorthash_KEYBYTES];
|
||||
char * provider_name;
|
||||
};
|
||||
|
||||
struct dnscrypt_query_header {
|
||||
uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
|
||||
uint8_t publickey[crypto_box_PUBLICKEYBYTES];
|
||||
uint8_t nonce[crypto_box_HALF_NONCEBYTES];
|
||||
uint8_t mac[crypto_box_MACBYTES];
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize DNSCrypt enviroment.
|
||||
* Initialize sodium library and allocate the dnsc_env structure.
|
||||
* \return an uninitialized struct dnsc_env.
|
||||
*/
|
||||
struct dnsc_env * dnsc_create(void);
|
||||
|
||||
/**
|
||||
* Apply configuration.
|
||||
* Read certificates and secret keys from configuration. Initialize hashkey and
|
||||
* provider name as well as loading cert TXT records.
|
||||
* In case of issue applying configuration, this function fatals.
|
||||
* \param[in] env the struct dnsc_env to populate.
|
||||
* \param[in] cfg the config_file struct with dnscrypt options.
|
||||
* \return 0 on success.
|
||||
*/
|
||||
int dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* handle a crypted dnscrypt request.
|
||||
* Determine wether or not a query is coming over the dnscrypt listener and
|
||||
* attempt to uncurve it or detect if it is a certificate query.
|
||||
* return 0 in case of failure.
|
||||
*/
|
||||
int dnsc_handle_curved_request(struct dnsc_env* dnscenv,
|
||||
struct comm_reply* repinfo);
|
||||
/**
|
||||
* handle an unencrypted dnscrypt request.
|
||||
* Determine wether or not a query is going over the dnscrypt channel and
|
||||
* attempt to curve it unless it was not crypted like when it is a
|
||||
* certificate query.
|
||||
* \return 0 in case of failure.
|
||||
*/
|
||||
|
||||
int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#endif
|
||||
@@ -1,25 +0,0 @@
|
||||
# dnscrypt.m4
|
||||
|
||||
# dnsc_DNSCRYPT([action-if-true], [action-if-false])
|
||||
# --------------------------------------------------------------------------
|
||||
# Check for required dnscrypt libraries and add dnscrypt configure args.
|
||||
AC_DEFUN([dnsc_DNSCRYPT],
|
||||
[
|
||||
AC_ARG_ENABLE([dnscrypt],
|
||||
AS_HELP_STRING([--enable-dnscrypt],
|
||||
[Enable dnscrypt support (requires libsodium)]),
|
||||
[opt_dnscrypt=$enableval], [opt_dnscrypt=no])
|
||||
|
||||
if test "x$opt_dnscrypt" != "xno"; then
|
||||
AC_ARG_WITH([libsodium], AC_HELP_STRING([--with-libsodium=path],
|
||||
[Path where libsodium is installed, for dnscrypt]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
])
|
||||
AC_SEARCH_LIBS([sodium_init], [sodium], [],
|
||||
AC_MSG_ERROR([The sodium library was not found. Please install sodium!]))
|
||||
$1
|
||||
else
|
||||
$2
|
||||
fi
|
||||
])
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef UNBOUND_DNSCRYPT_CONFIG_H
|
||||
#define UNBOUND_DNSCRYPT_CONFIG_H
|
||||
|
||||
/*
|
||||
* Process this file (dnscrypt_config.h.in) with AC_CONFIG_FILES to generate
|
||||
* dnscrypt_config.h.
|
||||
*
|
||||
* This file exists so that USE_DNSCRYPT can be used without including config.h.
|
||||
*/
|
||||
|
||||
#if @ENABLE_DNSCRYPT@ /* ENABLE_DNSCRYPT */
|
||||
# ifndef USE_DNSCRYPT
|
||||
# define USE_DNSCRYPT 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* UNBOUND_DNSCRYPT_CONFIG_H */
|
||||
-518
@@ -1,518 +0,0 @@
|
||||
/* dnstap support for Unbound */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Farsight Security, Inc.
|
||||
* 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. Neither the name of the copyright holder 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 "dnstap/dnstap_config.h"
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "config.h"
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/log.h"
|
||||
|
||||
#include <fstrm.h>
|
||||
#include <protobuf-c/protobuf-c.h>
|
||||
|
||||
#include "dnstap/dnstap.h"
|
||||
#include "dnstap/dnstap.pb-c.h"
|
||||
|
||||
#define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap"
|
||||
#define DNSTAP_INITIAL_BUF_SIZE 256
|
||||
|
||||
struct dt_msg {
|
||||
void *buf;
|
||||
size_t len_buf;
|
||||
Dnstap__Dnstap d;
|
||||
Dnstap__Message m;
|
||||
};
|
||||
|
||||
static int
|
||||
dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
{
|
||||
ProtobufCBufferSimple sbuf;
|
||||
|
||||
memset(&sbuf, 0, sizeof(sbuf));
|
||||
sbuf.base.append = protobuf_c_buffer_simple_append;
|
||||
sbuf.len = 0;
|
||||
sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE;
|
||||
sbuf.data = malloc(sbuf.alloced);
|
||||
if (sbuf.data == NULL)
|
||||
return 0;
|
||||
sbuf.must_free_data = 1;
|
||||
|
||||
*sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf);
|
||||
if (sbuf.data == NULL)
|
||||
return 0;
|
||||
*buf = sbuf.data;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
fstrm_res res;
|
||||
if (!buf)
|
||||
return;
|
||||
res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf,
|
||||
fstrm_free_wrapper, NULL);
|
||||
if (res != fstrm_res_success)
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_msg_init(const struct dt_env *env,
|
||||
struct dt_msg *dm,
|
||||
Dnstap__Message__Type mtype)
|
||||
{
|
||||
memset(dm, 0, sizeof(*dm));
|
||||
dm->d.base.descriptor = &dnstap__dnstap__descriptor;
|
||||
dm->m.base.descriptor = &dnstap__message__descriptor;
|
||||
dm->d.type = DNSTAP__DNSTAP__TYPE__MESSAGE;
|
||||
dm->d.message = &dm->m;
|
||||
dm->m.type = mtype;
|
||||
if (env->identity != NULL) {
|
||||
dm->d.identity.data = (uint8_t *) env->identity;
|
||||
dm->d.identity.len = (size_t) env->len_identity;
|
||||
dm->d.has_identity = 1;
|
||||
}
|
||||
if (env->version != NULL) {
|
||||
dm->d.version.data = (uint8_t *) env->version;
|
||||
dm->d.version.len = (size_t) env->len_version;
|
||||
dm->d.has_version = 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers)
|
||||
{
|
||||
#ifdef UNBOUND_DEBUG
|
||||
fstrm_res res;
|
||||
#endif
|
||||
struct dt_env *env;
|
||||
struct fstrm_iothr_options *fopt;
|
||||
struct fstrm_unix_writer_options *fuwopt;
|
||||
struct fstrm_writer *fw;
|
||||
struct fstrm_writer_options *fwopt;
|
||||
|
||||
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
|
||||
socket_path);
|
||||
log_assert(socket_path != NULL);
|
||||
log_assert(num_workers > 0);
|
||||
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
|
||||
fwopt = fstrm_writer_options_init();
|
||||
#ifdef UNBOUND_DEBUG
|
||||
res =
|
||||
#else
|
||||
(void)
|
||||
#endif
|
||||
fstrm_writer_options_add_content_type(fwopt,
|
||||
DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1);
|
||||
log_assert(res == fstrm_res_success);
|
||||
|
||||
fuwopt = fstrm_unix_writer_options_init();
|
||||
fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path);
|
||||
|
||||
fw = fstrm_unix_writer_init(fuwopt, fwopt);
|
||||
log_assert(fw != NULL);
|
||||
|
||||
fopt = fstrm_iothr_options_init();
|
||||
fstrm_iothr_options_set_num_input_queues(fopt, num_workers);
|
||||
env->iothr = fstrm_iothr_init(fopt, &fw);
|
||||
if (env->iothr == NULL) {
|
||||
verbose(VERB_DETAIL, "dt_create: fstrm_iothr_init() failed");
|
||||
fstrm_writer_destroy(&fw);
|
||||
free(env);
|
||||
env = NULL;
|
||||
}
|
||||
fstrm_iothr_options_destroy(&fopt);
|
||||
fstrm_unix_writer_options_destroy(&fuwopt);
|
||||
fstrm_writer_options_destroy(&fwopt);
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_apply_identity(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
char buf[MAXHOSTNAMELEN+1];
|
||||
if (!cfg->dnstap_send_identity)
|
||||
return;
|
||||
free(env->identity);
|
||||
if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) {
|
||||
if (gethostname(buf, MAXHOSTNAMELEN) == 0) {
|
||||
buf[MAXHOSTNAMELEN] = 0;
|
||||
env->identity = strdup(buf);
|
||||
} else {
|
||||
fatal_exit("dt_apply_identity: gethostname() failed");
|
||||
}
|
||||
} else {
|
||||
env->identity = strdup(cfg->dnstap_identity);
|
||||
}
|
||||
if (env->identity == NULL)
|
||||
fatal_exit("dt_apply_identity: strdup() failed");
|
||||
env->len_identity = (unsigned int)strlen(env->identity);
|
||||
verbose(VERB_OPS, "dnstap identity field set to \"%s\"",
|
||||
env->identity);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_apply_version(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap_send_version)
|
||||
return;
|
||||
free(env->version);
|
||||
if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0)
|
||||
env->version = strdup(PACKAGE_STRING);
|
||||
else
|
||||
env->version = strdup(cfg->dnstap_version);
|
||||
if (env->version == NULL)
|
||||
fatal_exit("dt_apply_version: strdup() failed");
|
||||
env->len_version = (unsigned int)strlen(env->version);
|
||||
verbose(VERB_OPS, "dnstap version field set to \"%s\"",
|
||||
env->version);
|
||||
}
|
||||
|
||||
void
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
if (!cfg->dnstap)
|
||||
return;
|
||||
|
||||
dt_apply_identity(env, cfg);
|
||||
dt_apply_version(env, cfg);
|
||||
if ((env->log_resolver_query_messages = (unsigned int)
|
||||
cfg->dnstap_log_resolver_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/RESOLVER_QUERY enabled");
|
||||
}
|
||||
if ((env->log_resolver_response_messages = (unsigned int)
|
||||
cfg->dnstap_log_resolver_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/RESOLVER_RESPONSE enabled");
|
||||
}
|
||||
if ((env->log_client_query_messages = (unsigned int)
|
||||
cfg->dnstap_log_client_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/CLIENT_QUERY enabled");
|
||||
}
|
||||
if ((env->log_client_response_messages = (unsigned int)
|
||||
cfg->dnstap_log_client_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/CLIENT_RESPONSE enabled");
|
||||
}
|
||||
if ((env->log_forwarder_query_messages = (unsigned int)
|
||||
cfg->dnstap_log_forwarder_query_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_QUERY enabled");
|
||||
}
|
||||
if ((env->log_forwarder_response_messages = (unsigned int)
|
||||
cfg->dnstap_log_forwarder_response_messages))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dt_init(struct dt_env *env)
|
||||
{
|
||||
env->ioq = fstrm_iothr_get_input_queue(env->iothr);
|
||||
if (env->ioq == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
dt_delete(struct dt_env *env)
|
||||
{
|
||||
if (!env)
|
||||
return;
|
||||
verbose(VERB_OPS, "closing dnstap socket");
|
||||
fstrm_iothr_destroy(&env->iothr);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
}
|
||||
|
||||
static void
|
||||
dt_fill_timeval(const struct timeval *tv,
|
||||
uint64_t *time_sec, protobuf_c_boolean *has_time_sec,
|
||||
uint32_t *time_nsec, protobuf_c_boolean *has_time_nsec)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
*time_sec = tv->tv_sec;
|
||||
*time_nsec = tv->tv_usec * 1000;
|
||||
#endif
|
||||
*has_time_sec = 1;
|
||||
*has_time_nsec = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_fill_buffer(sldns_buffer *b, ProtobufCBinaryData *p, protobuf_c_boolean *has)
|
||||
{
|
||||
log_assert(b != NULL);
|
||||
p->len = sldns_buffer_limit(b);
|
||||
p->data = sldns_buffer_begin(b);
|
||||
*has = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_msg_fill_net(struct dt_msg *dm,
|
||||
struct sockaddr_storage *ss,
|
||||
enum comm_point_type cptype,
|
||||
ProtobufCBinaryData *addr, protobuf_c_boolean *has_addr,
|
||||
uint32_t *port, protobuf_c_boolean *has_port)
|
||||
{
|
||||
log_assert(ss->ss_family == AF_INET6 || ss->ss_family == AF_INET);
|
||||
if (ss->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6 *s = (struct sockaddr_in6 *) ss;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = s->sin6_addr.s6_addr;
|
||||
addr->len = 16; /* IPv6 */
|
||||
*has_addr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin6_port);
|
||||
*has_port = 1;
|
||||
} else if (ss->ss_family == AF_INET) {
|
||||
struct sockaddr_in *s = (struct sockaddr_in *) ss;
|
||||
|
||||
/* socket_family */
|
||||
dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET;
|
||||
dm->m.has_socket_family = 1;
|
||||
|
||||
/* addr: query_address or response_address */
|
||||
addr->data = (uint8_t *) &s->sin_addr.s_addr;
|
||||
addr->len = 4; /* IPv4 */
|
||||
*has_addr = 1;
|
||||
|
||||
/* port: query_port or response_port */
|
||||
*port = ntohs(s->sin_port);
|
||||
*has_port = 1;
|
||||
}
|
||||
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
if (cptype == comm_udp) {
|
||||
/* socket_protocol */
|
||||
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
|
||||
dm->m.has_socket_protocol = 1;
|
||||
} else if (cptype == comm_tcp) {
|
||||
/* socket_protocol */
|
||||
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
|
||||
dm->m.has_socket_protocol = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *qmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
|
||||
/* type */
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_QUERY);
|
||||
|
||||
/* query_time */
|
||||
dt_fill_timeval(&qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
sldns_buffer *rmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval rtime;
|
||||
|
||||
gettimeofday(&rtime, NULL);
|
||||
|
||||
/* type */
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__CLIENT_RESPONSE);
|
||||
|
||||
/* response_time */
|
||||
dt_fill_timeval(&rtime,
|
||||
&dm.m.response_time_sec, &dm.m.has_response_time_sec,
|
||||
&dm.m.response_time_nsec, &dm.m.has_response_time_nsec);
|
||||
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, query_address, query_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, qsock, cptype,
|
||||
&dm.m.query_address, &dm.m.has_query_address,
|
||||
&dm.m.query_port, &dm.m.has_query_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
sldns_buffer *qmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
uint16_t qflags;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
qflags = sldns_buffer_read_u16_at(qmsg, 2);
|
||||
|
||||
/* type */
|
||||
if (qflags & BIT_RD) {
|
||||
if (!env->log_forwarder_query_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_QUERY);
|
||||
} else {
|
||||
if (!env->log_resolver_query_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__RESOLVER_QUERY);
|
||||
}
|
||||
|
||||
/* query_zone */
|
||||
dm.m.query_zone.data = zone;
|
||||
dm.m.query_zone.len = zone_len;
|
||||
dm.m.has_query_zone = 1;
|
||||
|
||||
/* query_time_sec, query_time_nsec */
|
||||
dt_fill_timeval(&qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* query_message */
|
||||
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
const struct timeval *qtime,
|
||||
const struct timeval *rtime,
|
||||
sldns_buffer *rmsg)
|
||||
{
|
||||
struct dt_msg dm;
|
||||
uint16_t qflags;
|
||||
|
||||
log_assert(qbuf_len >= sizeof(qflags));
|
||||
memcpy(&qflags, qbuf, sizeof(qflags));
|
||||
qflags = ntohs(qflags);
|
||||
|
||||
/* type */
|
||||
if (qflags & BIT_RD) {
|
||||
if (!env->log_forwarder_response_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__FORWARDER_RESPONSE);
|
||||
} else {
|
||||
if (!env->log_resolver_response_messages)
|
||||
return;
|
||||
dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__RESOLVER_RESPONSE);
|
||||
}
|
||||
|
||||
/* query_zone */
|
||||
dm.m.query_zone.data = zone;
|
||||
dm.m.query_zone.len = zone_len;
|
||||
dm.m.has_query_zone = 1;
|
||||
|
||||
/* query_time_sec, query_time_nsec */
|
||||
dt_fill_timeval(qtime,
|
||||
&dm.m.query_time_sec, &dm.m.has_query_time_sec,
|
||||
&dm.m.query_time_nsec, &dm.m.has_query_time_nsec);
|
||||
|
||||
/* response_time_sec, response_time_nsec */
|
||||
dt_fill_timeval(rtime,
|
||||
&dm.m.response_time_sec, &dm.m.has_response_time_sec,
|
||||
&dm.m.response_time_nsec, &dm.m.has_response_time_nsec);
|
||||
|
||||
/* response_message */
|
||||
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
|
||||
|
||||
/* socket_family, socket_protocol, response_address, response_port */
|
||||
log_assert(cptype == comm_udp || cptype == comm_tcp);
|
||||
dt_msg_fill_net(&dm, rsock, cptype,
|
||||
&dm.m.response_address, &dm.m.has_response_address,
|
||||
&dm.m.response_port, &dm.m.has_response_port);
|
||||
|
||||
if (dt_pack(&dm.d, &dm.buf, &dm.len_buf))
|
||||
dt_send(env, dm.buf, dm.len_buf);
|
||||
}
|
||||
|
||||
#endif /* USE_DNSTAP */
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
/* dnstap support for Unbound */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013-2014, Farsight Security, Inc.
|
||||
* 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. Neither the name of the copyright holder 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.
|
||||
*/
|
||||
|
||||
#ifndef UNBOUND_DNSTAP_H
|
||||
#define UNBOUND_DNSTAP_H
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
struct config_file;
|
||||
struct fstrm_io;
|
||||
struct fstrm_queue;
|
||||
struct sldns_buffer;
|
||||
|
||||
struct dt_env {
|
||||
/** dnstap I/O thread */
|
||||
struct fstrm_iothr *iothr;
|
||||
|
||||
/** dnstap I/O thread input queue */
|
||||
struct fstrm_iothr_queue *ioq;
|
||||
|
||||
/** dnstap "identity" field, NULL if disabled */
|
||||
char *identity;
|
||||
|
||||
/** dnstap "version" field, NULL if disabled */
|
||||
char *version;
|
||||
|
||||
/** length of "identity" field */
|
||||
unsigned len_identity;
|
||||
|
||||
/** length of "version" field */
|
||||
unsigned len_version;
|
||||
|
||||
/** whether to log Message/RESOLVER_QUERY */
|
||||
unsigned log_resolver_query_messages : 1;
|
||||
/** whether to log Message/RESOLVER_RESPONSE */
|
||||
unsigned log_resolver_response_messages : 1;
|
||||
/** whether to log Message/CLIENT_QUERY */
|
||||
unsigned log_client_query_messages : 1;
|
||||
/** whether to log Message/CLIENT_RESPONSE */
|
||||
unsigned log_client_response_messages : 1;
|
||||
/** whether to log Message/FORWARDER_QUERY */
|
||||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
unsigned log_forwarder_response_messages : 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create dnstap environment object. Afterwards, call dt_apply_cfg() to fill in
|
||||
* the config variables and dt_init() to fill in the per-worker state. Each
|
||||
* worker needs a copy of this object but with its own I/O queue (the fq field
|
||||
* of the structure) to ensure lock-free access to its own per-worker circular
|
||||
* queue. Duplicate the environment object if more than one worker needs to
|
||||
* share access to the dnstap I/O socket.
|
||||
* @param socket_path: path to dnstap logging socket, must be non-NULL.
|
||||
* @param num_workers: number of worker threads, must be > 0.
|
||||
* @return dt_env object, NULL on failure.
|
||||
*/
|
||||
struct dt_env *
|
||||
dt_create(const char *socket_path, unsigned num_workers);
|
||||
|
||||
/**
|
||||
* Apply config settings.
|
||||
* @param env: dnstap environment object.
|
||||
* @param cfg: new config settings.
|
||||
*/
|
||||
void
|
||||
dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
|
||||
|
||||
/**
|
||||
* Initialize per-worker state in dnstap environment object.
|
||||
* @param env: dnstap environment object to initialize, created with dt_create().
|
||||
* @return: true on success, false on failure.
|
||||
*/
|
||||
int
|
||||
dt_init(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* Delete dnstap environment object. Closes dnstap I/O socket and deletes all
|
||||
* per-worker I/O queues.
|
||||
*/
|
||||
void
|
||||
dt_delete(struct dt_env *env);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_QUERY.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param qmsg: query message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_query(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *qmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type CLIENT_RESPONSE.
|
||||
* @param env: dnstap environment object.
|
||||
* @param qsock: address/port of client.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param rmsg: response message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_client_response(struct dt_env *env,
|
||||
struct sockaddr_storage *qsock,
|
||||
enum comm_point_type cptype,
|
||||
struct sldns_buffer *rmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type RESOLVER_QUERY or
|
||||
* FORWARDER_QUERY. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the query is being sent to.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
* @param qmsg: query message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
struct sldns_buffer *qmsg);
|
||||
|
||||
/**
|
||||
* Create and send a new dnstap "Message" event of type RESOLVER_RESPONSE or
|
||||
* FORWARDER_RESPONSE. The type used is dependent on the value of the RD bit
|
||||
* in the query header.
|
||||
* @param env: dnstap environment object.
|
||||
* @param rsock: address/port of server the response was received from.
|
||||
* @param cptype: comm_udp or comm_tcp.
|
||||
* @param zone: query zone.
|
||||
* @param zone_len: length of zone.
|
||||
* @param qbuf: outside_network's qbuf key.
|
||||
* @param qbuf_len: length of outside_network's qbuf key.
|
||||
* @param qtime: time query message was sent.
|
||||
* @param rtime: time response message was sent.
|
||||
* @param rmsg: response message.
|
||||
*/
|
||||
void
|
||||
dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct sockaddr_storage *rsock,
|
||||
enum comm_point_type cptype,
|
||||
uint8_t *zone, size_t zone_len,
|
||||
uint8_t *qbuf, size_t qbuf_len,
|
||||
const struct timeval *qtime,
|
||||
const struct timeval *rtime,
|
||||
struct sldns_buffer *rmsg);
|
||||
|
||||
#endif /* USE_DNSTAP */
|
||||
|
||||
#endif /* UNBOUND_DNSTAP_H */
|
||||
@@ -1,56 +0,0 @@
|
||||
# dnstap.m4
|
||||
|
||||
# dt_DNSTAP(default_dnstap_socket_path, [action-if-true], [action-if-false])
|
||||
# --------------------------------------------------------------------------
|
||||
# Check for required dnstap libraries and add dnstap configure args.
|
||||
AC_DEFUN([dt_DNSTAP],
|
||||
[
|
||||
AC_ARG_ENABLE([dnstap],
|
||||
AS_HELP_STRING([--enable-dnstap],
|
||||
[Enable dnstap support (requires fstrm, protobuf-c)]),
|
||||
[opt_dnstap=$enableval], [opt_dnstap=no])
|
||||
|
||||
AC_ARG_WITH([dnstap-socket-path],
|
||||
AS_HELP_STRING([--with-dnstap-socket-path=pathname],
|
||||
[set default dnstap socket path]),
|
||||
[opt_dnstap_socket_path=$withval], [opt_dnstap_socket_path="$1"])
|
||||
|
||||
if test "x$opt_dnstap" != "xno"; then
|
||||
AC_PATH_PROG([PROTOC_C], [protoc-c])
|
||||
if test -z "$PROTOC_C"; then
|
||||
AC_MSG_ERROR([The protoc-c program was not found. Please install protobuf-c!])
|
||||
fi
|
||||
AC_ARG_WITH([protobuf-c], AC_HELP_STRING([--with-protobuf-c=path],
|
||||
[Path where protobuf-c is installed, for dnstap]), [
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I$withval/include/google"
|
||||
else
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
fi
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
], [
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
AC_ARG_WITH([libfstrm], AC_HELP_STRING([--with-libfstrm=path],
|
||||
[Path where libfstrm is installed, for dnstap]), [
|
||||
CFLAGS="$CFLAGS -I$withval/include"
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
])
|
||||
AC_SEARCH_LIBS([fstrm_iothr_init], [fstrm], [],
|
||||
AC_MSG_ERROR([The fstrm library was not found. Please install fstrm!]))
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
AC_MSG_ERROR([The protobuf-c library was not found. Please install protobuf-c!]))
|
||||
$2
|
||||
else
|
||||
$3
|
||||
fi
|
||||
])
|
||||
@@ -1,262 +0,0 @@
|
||||
// dnstap: flexible, structured event replication format for DNS software
|
||||
//
|
||||
// This file contains the protobuf schemas for the "dnstap" structured event
|
||||
// replication format for DNS software.
|
||||
|
||||
// Written in 2013-2014 by Farsight Security, Inc.
|
||||
//
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this file to the public
|
||||
// domain worldwide. This file is distributed without any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication along
|
||||
// with this file. If not, see:
|
||||
//
|
||||
// <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
|
||||
package dnstap;
|
||||
|
||||
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
|
||||
// contains other kinds of dnstap payloads, although currently only one type
|
||||
// of dnstap payload is defined.
|
||||
// See: https://developers.google.com/protocol-buffers/docs/techniques#union
|
||||
message Dnstap {
|
||||
// DNS server identity.
|
||||
// If enabled, this is the identity string of the DNS server which generated
|
||||
// this message. Typically this would be the same string as returned by an
|
||||
// "NSID" (RFC 5001) query.
|
||||
optional bytes identity = 1;
|
||||
|
||||
// DNS server version.
|
||||
// If enabled, this is the version string of the DNS server which generated
|
||||
// this message. Typically this would be the same string as returned by a
|
||||
// "version.bind" query.
|
||||
optional bytes version = 2;
|
||||
|
||||
// Extra data for this payload.
|
||||
// This field can be used for adding an arbitrary byte-string annotation to
|
||||
// the payload. No encoding or interpretation is applied or enforced.
|
||||
optional bytes extra = 3;
|
||||
|
||||
// Identifies which field below is filled in.
|
||||
enum Type {
|
||||
MESSAGE = 1;
|
||||
}
|
||||
required Type type = 15;
|
||||
|
||||
// One of the following will be filled in.
|
||||
optional Message message = 14;
|
||||
}
|
||||
|
||||
// SocketFamily: the network protocol family of a socket. This specifies how
|
||||
// to interpret "network address" fields.
|
||||
enum SocketFamily {
|
||||
INET = 1; // IPv4 (RFC 791)
|
||||
INET6 = 2; // IPv6 (RFC 2460)
|
||||
}
|
||||
|
||||
// SocketProtocol: the transport protocol of a socket. This specifies how to
|
||||
// interpret "transport port" fields.
|
||||
enum SocketProtocol {
|
||||
UDP = 1; // User Datagram Protocol (RFC 768)
|
||||
TCP = 2; // Transmission Control Protocol (RFC 793)
|
||||
}
|
||||
|
||||
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
|
||||
// metadata. Applications generating "Message" payloads should follow
|
||||
// certain requirements based on the MessageType, see below.
|
||||
message Message {
|
||||
|
||||
// There are eight types of "Message" defined that correspond to the
|
||||
// four arrows in the following diagram, slightly modified from RFC 1035
|
||||
// section 2:
|
||||
|
||||
// +---------+ +----------+ +--------+
|
||||
// | | query | | query | |
|
||||
// | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. |
|
||||
// | Resolver| | Server | | Name |
|
||||
// | |<-SR--------CR-| |<-RR----AR-| Server |
|
||||
// +---------+ response | | response | |
|
||||
// +----------+ +--------+
|
||||
|
||||
// Each arrow has two Type values each, one for each "end" of each arrow,
|
||||
// because these are considered to be distinct events. Each end of each
|
||||
// arrow on the diagram above has been marked with a two-letter Type
|
||||
// mnemonic. Clockwise from upper left, these mnemonic values are:
|
||||
//
|
||||
// SQ: STUB_QUERY
|
||||
// CQ: CLIENT_QUERY
|
||||
// RQ: RESOLVER_QUERY
|
||||
// AQ: AUTH_QUERY
|
||||
// AR: AUTH_RESPONSE
|
||||
// RR: RESOLVER_RESPONSE
|
||||
// CR: CLIENT_RESPONSE
|
||||
// SR: STUB_RESPONSE
|
||||
|
||||
// Two additional types of "Message" have been defined for the
|
||||
// "forwarding" case where an upstream DNS server is responsible for
|
||||
// further recursion. These are not shown on the diagram above, but have
|
||||
// the following mnemonic values:
|
||||
|
||||
// FQ: FORWARDER_QUERY
|
||||
// FR: FORWARDER_RESPONSE
|
||||
|
||||
// The "Message" Type values are defined below.
|
||||
|
||||
enum Type {
|
||||
// AUTH_QUERY is a DNS query message received from a resolver by an
|
||||
// authoritative name server, from the perspective of the authoritative
|
||||
// name server.
|
||||
AUTH_QUERY = 1;
|
||||
|
||||
// AUTH_RESPONSE is a DNS response message sent from an authoritative
|
||||
// name server to a resolver, from the perspective of the authoritative
|
||||
// name server.
|
||||
AUTH_RESPONSE = 2;
|
||||
|
||||
// RESOLVER_QUERY is a DNS query message sent from a resolver to an
|
||||
// authoritative name server, from the perspective of the resolver.
|
||||
// Resolvers typically clear the RD (recursion desired) bit when
|
||||
// sending queries.
|
||||
RESOLVER_QUERY = 3;
|
||||
|
||||
// RESOLVER_RESPONSE is a DNS response message received from an
|
||||
// authoritative name server by a resolver, from the perspective of
|
||||
// the resolver.
|
||||
RESOLVER_RESPONSE = 4;
|
||||
|
||||
// CLIENT_QUERY is a DNS query message sent from a client to a DNS
|
||||
// server which is expected to perform further recursion, from the
|
||||
// perspective of the DNS server. The client may be a stub resolver or
|
||||
// forwarder or some other type of software which typically sets the RD
|
||||
// (recursion desired) bit when querying the DNS server. The DNS server
|
||||
// may be a simple forwarding proxy or it may be a full recursive
|
||||
// resolver.
|
||||
CLIENT_QUERY = 5;
|
||||
|
||||
// CLIENT_RESPONSE is a DNS response message sent from a DNS server to
|
||||
// a client, from the perspective of the DNS server. The DNS server
|
||||
// typically sets the RA (recursion available) bit when responding.
|
||||
CLIENT_RESPONSE = 6;
|
||||
|
||||
// FORWARDER_QUERY is a DNS query message sent from a downstream DNS
|
||||
// server to an upstream DNS server which is expected to perform
|
||||
// further recursion, from the perspective of the downstream DNS
|
||||
// server.
|
||||
FORWARDER_QUERY = 7;
|
||||
|
||||
// FORWARDER_RESPONSE is a DNS response message sent from an upstream
|
||||
// DNS server performing recursion to a downstream DNS server, from the
|
||||
// perspective of the downstream DNS server.
|
||||
FORWARDER_RESPONSE = 8;
|
||||
|
||||
// STUB_QUERY is a DNS query message sent from a stub resolver to a DNS
|
||||
// server, from the perspective of the stub resolver.
|
||||
STUB_QUERY = 9;
|
||||
|
||||
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
|
||||
// stub resolver, from the perspective of the stub resolver.
|
||||
STUB_RESPONSE = 10;
|
||||
}
|
||||
|
||||
// One of the Type values described above.
|
||||
required Type type = 1;
|
||||
|
||||
// One of the SocketFamily values described above.
|
||||
optional SocketFamily socket_family = 2;
|
||||
|
||||
// One of the SocketProtocol values described above.
|
||||
optional SocketProtocol socket_protocol = 3;
|
||||
|
||||
// The network address of the message initiator.
|
||||
// For SocketFamily INET, this field is 4 octets (IPv4 address).
|
||||
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
|
||||
optional bytes query_address = 4;
|
||||
|
||||
// The network address of the message responder.
|
||||
// For SocketFamily INET, this field is 4 octets (IPv4 address).
|
||||
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
|
||||
optional bytes response_address = 5;
|
||||
|
||||
// The transport port of the message initiator.
|
||||
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
|
||||
optional uint32 query_port = 6;
|
||||
|
||||
// The transport port of the message responder.
|
||||
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
|
||||
optional uint32 response_port = 7;
|
||||
|
||||
// The time at which the DNS query message was sent or received, depending
|
||||
// on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY.
|
||||
// This is the number of seconds since the UNIX epoch.
|
||||
optional uint64 query_time_sec = 8;
|
||||
|
||||
// The time at which the DNS query message was sent or received.
|
||||
// This is the seconds fraction, expressed as a count of nanoseconds.
|
||||
optional fixed32 query_time_nsec = 9;
|
||||
|
||||
// The initiator's original wire-format DNS query message, verbatim.
|
||||
optional bytes query_message = 10;
|
||||
|
||||
// The "zone" or "bailiwick" pertaining to the DNS query message.
|
||||
// This is a wire-format DNS domain name.
|
||||
optional bytes query_zone = 11;
|
||||
|
||||
// The time at which the DNS response message was sent or received,
|
||||
// depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or
|
||||
// CLIENT_RESPONSE.
|
||||
// This is the number of seconds since the UNIX epoch.
|
||||
optional uint64 response_time_sec = 12;
|
||||
|
||||
// The time at which the DNS response message was sent or received.
|
||||
// This is the seconds fraction, expressed as a count of nanoseconds.
|
||||
optional fixed32 response_time_nsec = 13;
|
||||
|
||||
// The responder's original wire-format DNS response message, verbatim.
|
||||
optional bytes response_message = 14;
|
||||
}
|
||||
|
||||
// All fields except for 'type' in the Message schema are optional.
|
||||
// It is recommended that at least the following fields be filled in for
|
||||
// particular types of Messages.
|
||||
|
||||
// AUTH_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_address, query_port
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
|
||||
// AUTH_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_address, query_port
|
||||
// query_time_sec, query_time_nsec
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
||||
|
||||
// RESOLVER_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_name, query_type, query_class
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
// query_zone
|
||||
// response_address, response_port
|
||||
|
||||
// RESOLVER_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_name, query_type, query_class
|
||||
// query_time_sec, query_time_nsec
|
||||
// query_zone
|
||||
// response_address, response_port
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
||||
|
||||
// CLIENT_QUERY:
|
||||
// socket_family, socket_protocol
|
||||
// query_message
|
||||
// query_time_sec, query_time_nsec
|
||||
|
||||
// CLIENT_RESPONSE:
|
||||
// socket_family, socket_protocol
|
||||
// query_time_sec, query_time_nsec
|
||||
// response_message
|
||||
// response_time_sec, response_time_nsec
|
||||
@@ -1,17 +0,0 @@
|
||||
#ifndef UNBOUND_DNSTAP_CONFIG_H
|
||||
#define UNBOUND_DNSTAP_CONFIG_H
|
||||
|
||||
/*
|
||||
* Process this file (dnstap_config.h.in) with AC_CONFIG_FILES to generate
|
||||
* dnstap_config.h.
|
||||
*
|
||||
* This file exists so that USE_DNSTAP can be used without including config.h.
|
||||
*/
|
||||
|
||||
#if @ENABLE_DNSTAP@ /* ENABLE_DNSTAP */
|
||||
# ifndef USE_DNSTAP
|
||||
# define USE_DNSTAP 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* UNBOUND_DNSTAP_CONFIG_H */
|
||||
Binary file not shown.
+1
-8
@@ -11,13 +11,6 @@ At NLnet Labs, Jelte Jansen, Mark Santcroos and Matthijs Mekking
|
||||
reviewed the unbound C sources.
|
||||
|
||||
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
|
||||
|
||||
Ondřej Surý - running coverity analysis tool on 0.9 dev version.
|
||||
Alexander Gall - multihomed, anycast testing of unbound resolver server.
|
||||
Zdenek Vasicek and Marek Vavrusa - python module.
|
||||
cz.nic - sponsoring 'summer of code' development by Zdenek and Marek.
|
||||
Brett Carr - windows beta testing.
|
||||
Luca Bruno - patch for windows support in libunbound hosts and resolvconf().
|
||||
Tom Hendrikx - contributed split-itar.sh a useful script to 5011-track ITAR.
|
||||
Daisuke HIGASHI - patch for rrset-roundrobin and minimal-responses.
|
||||
Simon Perrault - DNS64 module.
|
||||
Robert Edmonds - dnstap code.
|
||||
|
||||
+12
-4490
File diff suppressed because it is too large
Load Diff
+21
-33
@@ -12,45 +12,31 @@ Big Features
|
||||
Recursive service.
|
||||
Caching service.
|
||||
Forwarding and stub zones.
|
||||
Very limited authoritative service.
|
||||
No authoritative service.
|
||||
DNSSEC Validation options.
|
||||
EDNS0, NSEC3, IPv6, DNAME, Unknown-RR-types.
|
||||
RSASHA256, GOST, ECDSA, SHA384 DNSSEC algorithms.
|
||||
EDNS0, NSEC3, Unknown-RR-types.
|
||||
|
||||
|
||||
Details
|
||||
-------
|
||||
Processing support
|
||||
RFC 1034-1035: as a recursive, caching server. Not authoritative.
|
||||
including CNAMEs, referrals, wildcards, classes, ...
|
||||
AAAA type, and IP6 dual stack support.
|
||||
type ANY queries are supported, class ANY queries are supported.
|
||||
RFC 1123, 6.1 Requirements for DNS of internet hosts.
|
||||
RFC 4033-4035: as a validating caching server (unbound daemon).
|
||||
as a validating stub (libunbound).
|
||||
RFC 1918.
|
||||
RFC 1995, 1996, 2136: not authoritative, so no AXFR, IXFR, NOTIFY or
|
||||
dynamic update services are appropriate.
|
||||
RFC 2181: completely, including the trust model, keeping rrsets together.
|
||||
RFC 2308: TTL directive, and the rest of the RFC too.
|
||||
RFC 2671: EDNS0 support, default advertisement 4Kb size.
|
||||
RFC 2672: DNAME support.
|
||||
RFC 3597: Unknown RR type support.
|
||||
RFC 4343: case insensitive handling of domain names.
|
||||
RFC 4509: SHA256 DS hash.
|
||||
RFC 4592: wildcards.
|
||||
RFC 4697: No DNS Resolution Misbehavior.
|
||||
RFC 5011: update of trust anchors with timers.
|
||||
RFC 2671: EDNS0 support, default advertisement 4Kb size.
|
||||
RFC 5155: NSEC3, NSEC3PARAM types
|
||||
RFC 5358: reflectors-are-evil: access control list for recursive
|
||||
service. In fact for all DNS service so cache snooping is halted.
|
||||
RFC 5452: forgery resilience. all recommendations followed.
|
||||
RFC 5702: RSASHA256 signature algorithm.
|
||||
RFC 5933: GOST signature algorithm.
|
||||
RFC 6303: default local zones.
|
||||
It is possible to block zones or return an address for localhost.
|
||||
This is a very limited authoritative service. Defaults as in draft.
|
||||
RFC 6604: xNAME RCODE and status bits.
|
||||
RFC 6605: ECDSA signature algorithm, SHA384 DS hash.
|
||||
AAAA type. and IP6 dual stack support.
|
||||
type ANY queries are supported.
|
||||
RFC 2308: TTL directive, and the rest of the RFC too.
|
||||
RFC 4592: wildcards.
|
||||
|
||||
RFC 1995, 1996, 2136: not authoritative, so no AXFR, IXFR, NOTIFY or
|
||||
dynamic update services are appropriate.
|
||||
|
||||
chroot and drop-root-privileges support, default enabled in config file.
|
||||
|
||||
@@ -58,23 +44,27 @@ AD bit in query can be used to request AD bit in response (w/o using DO bit).
|
||||
CD bit in query can be used to request bogus data.
|
||||
UDP and TCP service is provided downstream.
|
||||
UDP and TCP are used to request from upstream servers.
|
||||
SSL wrapped TCP service can be used upstream and provided downstream.
|
||||
Multiple queries can be made over a TCP stream.
|
||||
|
||||
No TSIG support at this time.
|
||||
No SIG0 support at this time.
|
||||
No dTLS support at this time.
|
||||
This is not a DNS statistics package, but some operationally useful
|
||||
values are provided via unbound-control stats.
|
||||
TXT RRs from the Chaos class (id.server, hostname.bind, ...) are supported.
|
||||
values are provided.
|
||||
TXT RRs from the Chaos class (id.server, hostname.bind, ...) supported.
|
||||
|
||||
draft-0x20: implemented, use caps-for-id option to enable use.
|
||||
Also implements bitwise echo of the query to support downstream 0x20.
|
||||
draft-forgery-resilience: all recommendations followed.
|
||||
draft-0x20: experimental implementation (incomplete).
|
||||
implements bitwise echo of the query to support downstream 0x20.
|
||||
draft-ietf-dnsop-default-local-zones is fully supported (-04).
|
||||
It is possible to block zones or return an address for localhost.
|
||||
This is a very limited authoritative service. Defaults as in draft.
|
||||
draft-ietf-dnsop-resolver-priming(-00): can prime and can fallback to
|
||||
a safety belt list.
|
||||
draft-ietf-dnsop-dnssec-trust-anchor(-01): DS records can be configured
|
||||
as trust anchors. Also DNSKEYs are allowed, by the way.
|
||||
draft-ietf-dnsext-dnssec-bis-updates: supported.
|
||||
draft-ietf-dnsop-reflectors-are-evil: access control list for recursive
|
||||
service. In fact for all DNS service so cache snooping is halted.
|
||||
|
||||
Record type syntax support, extensive, from lib ldns.
|
||||
For these types only syntax and parsing support is needed.
|
||||
@@ -92,12 +82,10 @@ AAAA type
|
||||
2672: DNAME type.
|
||||
OPT type
|
||||
3123: APL
|
||||
3596: AAAA
|
||||
SSHFP type
|
||||
4025: IPSECKEY
|
||||
4033-4035: DS, RRSIG, NSEC, DNSKEY
|
||||
4701: DHCID
|
||||
5155: NSEC3, NSEC3PARAM
|
||||
4408: SPF
|
||||
6944: DNSKEY algorithm status
|
||||
|
||||
|
||||
Binary file not shown.
+10
-10
@@ -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.
|
||||
|
||||
+19
-67
@@ -3,8 +3,6 @@ Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
This software is under BSD license, see LICENSE for details.
|
||||
The DNS64 module has BSD license in dns64/dns64.c.
|
||||
The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
|
||||
* Download the latest release version of this software from
|
||||
http://unbound.net
|
||||
@@ -12,11 +10,17 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
http://unbound.net/svn/
|
||||
|
||||
* Uses the following libraries;
|
||||
* ldns http://www.nlnetlabs.nl/ldns/ (BSD license)
|
||||
(required) can use tarball from source directory.
|
||||
* libevent http://www.monkey.org/~provos/libevent/ (BSD license)
|
||||
(optional) can use builtin alternative instead.
|
||||
* libexpat (for the unbound-anchor helper program) (MIT license)
|
||||
|
||||
* Make and install: ./configure; make; make install
|
||||
* Use GNU make; default on linux, often called 'gmake' on BSD and Solaris.
|
||||
* --with-ldns=/path/to/ldns
|
||||
If ldns is not detected on the system, a prepackaged tarball
|
||||
of the ldns library is used to compile and statically link against.
|
||||
If detected on the system, it will dynamically link against it.
|
||||
* --with-libevent=/path/to/libevent
|
||||
Can be set to either the system install or the build directory.
|
||||
--with-libevent=no (default) gives a builtin alternative
|
||||
@@ -24,19 +28,13 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
of outgoing ports. This improves randomization and spoof
|
||||
resistance. For the default of 16 ports the builtin alternative
|
||||
works well and is a little faster.
|
||||
* --with-libexpat=/path/to/libexpat
|
||||
Can be set to the install directory of libexpat.
|
||||
* --without-pthreads
|
||||
This disables pthreads. Without this option the pthreads library
|
||||
is detected automatically. Use this option to disable threading
|
||||
altogether, or, on Solaris, also use --with(out)-solaris-threads.
|
||||
* --enable-checking
|
||||
This enables assertions in the code that guard against a variety of
|
||||
programming errors, among which buffer overflows. The program exits
|
||||
with an error if an assertion fails (but the buffer did not overflow).
|
||||
* --enable-static-exe
|
||||
This enables a debug option to statically link against the
|
||||
libevent library.
|
||||
This enables a debug option to statically link, against ldns and
|
||||
libevent libraries.
|
||||
* --enable-lock-checks
|
||||
This enables a debug option to check lock and unlock calls. It needs
|
||||
a recent pthreads library to work.
|
||||
@@ -57,39 +55,27 @@ The DNSTAP code has BSD license in dnstap/dnstap.c.
|
||||
* --with-chroot-dir=path
|
||||
Set default chroot directory,
|
||||
the default is /usr/local/etc/unbound.
|
||||
* --with-rootkey-file=path
|
||||
Set the default root.key path. This file is read and written.
|
||||
the default is /usr/local/etc/unbound/root.key
|
||||
* --with-rootcert-file=path
|
||||
Set the default root update certificate path. A builtin certificate
|
||||
is used if this file is empty or does not exist.
|
||||
the default is /usr/local/etc/unbound/icannbundle.pem
|
||||
* --with-username=user
|
||||
Set default user name to change to,
|
||||
the default is the "unbound" user.
|
||||
* --with-pyunbound
|
||||
Create libunbound wrapper usable from python.
|
||||
Needs python-devel and swig development tools.
|
||||
* --with-pythonmodule
|
||||
Compile the python module that processes responses in the server.
|
||||
* --disable-sha2
|
||||
Disable support for RSASHA256 and RSASHA512 crypto.
|
||||
* --disable-gost
|
||||
Disable support for GOST crypto, RFC 5933.
|
||||
|
||||
* 'make test' runs a series of self checks.
|
||||
* 'make test' attempts to run a series of tests, depending on the support
|
||||
programs that are installed.
|
||||
|
||||
Known issues
|
||||
------------
|
||||
o If there are no replies for a forward or stub zone, for a reverse zone,
|
||||
you may need to add a local-zone: name transparent or nodefault to the
|
||||
server: section of the config file to unblock the reverse zone.
|
||||
Only happens for (sub)zones that are blocked by default; e.g. 10.in-addr.arpa
|
||||
o If libevent is older (before 1.3c), unbound will exit instead of reload
|
||||
on sighup. On a restart 'did not exit gracefully last time' warning is
|
||||
printed. Perform ./configure --with-libevent=no or update libevent, rerun
|
||||
configure and recompile unbound to make sighup work correctly.
|
||||
It is strongly suggested to use a recent version of libevent.
|
||||
It is strongly suggested to use the latest version of libevent (1.4 or more)
|
||||
on Solaris, because of fixes in the solaris event port code in libevent.
|
||||
o If you receive no answers deploying unbound on a private network.
|
||||
Check that the zone you configure as a stub zone is correct, listing working
|
||||
ip-addresses. Check that the NS data in the zone, those hostnames, are
|
||||
in fact those same, working, ip-addresses. Unbound will fetch the NS data
|
||||
from the zone and use that information in preference to the config
|
||||
information.
|
||||
o If you are not receiving the correct source IP address on replies (e.g.
|
||||
you are running a multihomed, anycast server), the interface-automatic
|
||||
option can be enabled to set socket options to achieve the correct
|
||||
@@ -101,14 +87,6 @@ o The warning 'openssl has no entropy, seeding with time', with chroot
|
||||
o On Solaris 5.10 some libtool packages from repositories do not work with
|
||||
gcc, showing errors gcc: unrecognized option `-KPIC'
|
||||
To solve this do ./configure libtool=./libtool [your options...].
|
||||
On Solaris you may pass CFLAGS="-xO4 -xtarget=generic" if you use sun-cc.
|
||||
o If unbound-control (or munin graphs) do not work, this can often be because
|
||||
the unbound-control-setup script creates the keys with restricted
|
||||
permissions, and the files need to be made readable or ownered by both the
|
||||
unbound daemon and unbound-control.
|
||||
o Crosscompile seems to hang. You tried to install unbound under wine.
|
||||
wine regedit and remove all the unbound entries from the registry or
|
||||
delete .wine/drive_c.
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
@@ -120,30 +98,4 @@ o Other code origins are from the NSD (NLnet Labs) and LDNS (NLnet Labs)
|
||||
projects. Such as buffer, region-allocator and red-black tree code.
|
||||
o See Credits file for contributors.
|
||||
|
||||
|
||||
Your Support
|
||||
------------
|
||||
NLnet Labs offers all of its software products as open source, most are
|
||||
published under a BSD license. You can download them, not only from the
|
||||
NLnet Labs website but also through the various OS distributions for
|
||||
which NSD, ldns, and Unbound are packaged. We therefore have little idea
|
||||
who uses our software in production environments and have no direct ties
|
||||
with 'our customers'.
|
||||
|
||||
Therefore, we ask you to contact us at users@NLnetLabs.nl and tell us
|
||||
whether you use one of our products in your production environment,
|
||||
what that environment looks like, and maybe even share some praise.
|
||||
We would like to refer to the fact that your organization is using our
|
||||
products. We will only do that if you explicitly allow us. In all other
|
||||
cases we will keep the information you share with us to ourselves.
|
||||
|
||||
In addition to the moral support you can also support us
|
||||
financially. NLnet Labs is a recognized not-for-profit charity foundation
|
||||
that is chartered to develop open-source software and open-standards
|
||||
for the Internet. If you use our software to satisfaction please express
|
||||
that by giving us a donation. For small donations PayPal can be used. For
|
||||
larger and regular donations please contact us at users@NLnetLabs.nl. Also
|
||||
see http://www.nlnetlabs.nl/labs/contributors/.
|
||||
|
||||
|
||||
* mailto:unbound-bugs@nlnetlabs.nl
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
The DNS64 code was written by Viagenie, 2009, by Simon Perrault as part
|
||||
of the Ecdysis project. The code is copyright by them, and has the BSD
|
||||
license (see the dns64/dns64.c file).
|
||||
|
||||
To enable DNS64 functionality in Unbound, two directives in unbound.conf must
|
||||
be edited:
|
||||
|
||||
1. The "module-config" directive must start with "dns64". For example:
|
||||
|
||||
module-config: "dns64 validator iterator"
|
||||
|
||||
If you're not using DNSSEC then you may remove "validator".
|
||||
|
||||
2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
|
||||
|
||||
dns64-prefix: 64:FF9B::/96
|
||||
|
||||
The prefix must be a /96 or shorter.
|
||||
|
||||
To test that things are working right, perform a query against Unbound for a
|
||||
domain name for which no AAAA record exists. You should see a AAAA record in
|
||||
the answer section. The corresponding IPv6 address will be inside the DNS64
|
||||
prefix. For example:
|
||||
|
||||
$ unbound -c unbound.conf
|
||||
$ dig @localhost jazz-v4.viagenie.ca aaaa
|
||||
[...]
|
||||
;; ANSWER SECTION:
|
||||
jazz-v4.viagenie.ca. 86400 IN AAAA 64:ff9b::ce7b:1f02
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
README.svn
|
||||
|
||||
For a svn checkout:
|
||||
For a svn checkout
|
||||
* configure script, aclocal.m4, as well as yacc/lex output files are
|
||||
committed to the repository.
|
||||
* use --enable-debug flag for configure to enable dependency tracking and
|
||||
|
||||
+7
-6
@@ -1,20 +1,21 @@
|
||||
README unbound tests
|
||||
|
||||
For a quick test that runs unit tests and state machine tests, use
|
||||
There is a test setup for unbound. Use
|
||||
make test
|
||||
|
||||
There is a long test setup for unbound that needs tools installed. Use
|
||||
make longtest
|
||||
To make and run the long tests. The results are summarized at the end.
|
||||
To make and run the tests. The results are summarized at the end.
|
||||
|
||||
You need to have the following programs installed and in your PATH.
|
||||
* dig - from the bind-tools package. Used to send DNS queries.
|
||||
* splint (optional) - for lint test
|
||||
* doxygen (optional) - for doc completeness test
|
||||
* ldns-testns - from ldns examples. Used as DNS auth server.
|
||||
* ldns-testns (optional) - from ldns examples. Used as DNS auth server.
|
||||
* xxd and nc (optional) - for (malformed) packet transmission.
|
||||
The optional programs are detected and can be omitted.
|
||||
|
||||
Without any support programs, unittest and testbound can still be used.
|
||||
(cd testdata; ../testcode/mini_tpkg.sh exe 02-unittest.tpkg)
|
||||
(cd testdata; ../testcode/mini_tpkg.sh exe 03-testbound.tpkg)
|
||||
|
||||
testdata/ contains the data for tests.
|
||||
testcode/ contains scripts and c code for the tests.
|
||||
|
||||
|
||||
@@ -35,15 +35,12 @@ o overhaul outside-network servicedquery to merge with udpwait and tcpwait,
|
||||
o check into rebinding ports for efficiency, configure time test.
|
||||
o EVP hardware crypto support.
|
||||
o option to ignore all inception and expiration dates for rrsigs.
|
||||
o option to use builtin ldns explicitly. Or stop shipping builtin tarball.
|
||||
o cleaner code; return and func statements on newline.
|
||||
o memcached module that sits before validator module; checks for memcached
|
||||
data (on local lan), stores recursion lookup. Provides one cache for multiple resolver machines, coherent reply content in anycast setup.
|
||||
data (on local lan), stores recursion lookup. Provides one cache for
|
||||
multiple resolver machines, coherent reply content in anycast setup.
|
||||
o no openssl_add_all_algorithms, but only the ones necessary, less space.
|
||||
o listen to NOTIFY messages for zones and flush the cache for that zone
|
||||
if received. Useful when also having a stub to that auth server.
|
||||
Needs proper protection, TSIG, in place.
|
||||
o winevent - do not go more than 64 fds (by polling with select one by
|
||||
one), win95/98 have 100fd limit in the kernel, so this ruins w9x portability.
|
||||
|
||||
*** Features features, for later
|
||||
* dTLS, TLS, look to need special port numbers, cert storage, recent libssl.
|
||||
@@ -54,23 +51,13 @@ o winevent - do not go more than 64 fds (by polling with select one by
|
||||
of responses over a time interval is collected, and each is validated.
|
||||
or try in TCP mode. Do not 'try all servers several times', since we must
|
||||
not create packet storms with operator errors.
|
||||
* Windows port features
|
||||
o on windows version, implement that OS ancillary data capabilities for
|
||||
interface-automatic. IPPKTINFO, IP6PKTINFO for WSARecvMsg, WSASendMsg.
|
||||
o local-zone directive with authority service, full authority server
|
||||
is a non-goal.
|
||||
o infra and lame cache: easier size config (in Mb), show usage in graphs.
|
||||
- store time of dump in cachedumps, so that on a load the ttls can be
|
||||
compared to the absolute time, and now-expired items can be dealt with.
|
||||
|
||||
later
|
||||
- selective verbosity; ubcontrol trace example.com
|
||||
- cache fork-dump, pre-load
|
||||
- for fwds, send queries to N servers in fwd-list, use first reply.
|
||||
document high scalable, high available unbound setup onepager.
|
||||
- prefetch DNSKEY when DS in delegation seen (nonCD, underTA).
|
||||
- use libevent if available on system by default(?), default outgoing 256to1024
|
||||
|
||||
[1] BIND-like query logging to see who's looking up what and when
|
||||
[2] more logging about stuff like SERVFAIL and REFUSED responses
|
||||
[3] a Makefile that works without gnumake
|
||||
|
||||
o configure option to force use of builtin ldns tarball.
|
||||
o include /etc/pki/dnssec-keys/production/*.conf with wildcard support.
|
||||
o make so revoke bit keys cannot verify signatures
|
||||
o option to print UTC timestamps instead of epoch in seconds.
|
||||
o print querier IP address on high loglevels.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user