MFV r368464:

Update unbound from 1.12.0 to 1.13.0

MFC after:	1 week
Security:	CVE-2020-28935
This commit is contained in:
Cy Schubert 2020-12-09 02:59:24 +00:00
commit 369c692350
54 changed files with 2535 additions and 612 deletions

View File

@ -2,7 +2,7 @@
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright 1992-2020 Free Software Foundation, Inc. # Copyright 1992-2020 Free Software Foundation, Inc.
timestamp='2020-09-19' timestamp='2020-11-19'
# This file is free software; you can redistribute it and/or modify it # 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 # under the terms of the GNU General Public License as published by
@ -27,12 +27,12 @@ timestamp='2020-09-19'
# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
# #
# You can get the latest version of this script from: # You can get the latest version of this script from:
# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
# #
# Please send patches to <config-patches@gnu.org>. # Please send patches to <config-patches@gnu.org>.
me=`echo "$0" | sed -e 's,.*/,,'` me=$(echo "$0" | sed -e 's,.*/,,')
usage="\ usage="\
Usage: $0 [OPTION] Usage: $0 [OPTION]
@ -103,7 +103,7 @@ set_cc_for_build() {
test "$tmp" && return 0 test "$tmp" && return 0
: "${TMPDIR=/tmp}" : "${TMPDIR=/tmp}"
# shellcheck disable=SC2039 # shellcheck disable=SC2039
{ tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { tmp=$( (umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null) && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
@ -131,16 +131,14 @@ if test -f /.attbin/uname ; then
PATH=$PATH:/.attbin ; export PATH PATH=$PATH:/.attbin ; export PATH
fi fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_MACHINE=$( (uname -m) 2>/dev/null) || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_RELEASE=$( (uname -r) 2>/dev/null) || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_SYSTEM=$( (uname -s) 2>/dev/null) || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown UNAME_VERSION=$( (uname -v) 2>/dev/null) || UNAME_VERSION=unknown
case "$UNAME_SYSTEM" in case "$UNAME_SYSTEM" in
Linux|GNU|GNU/*) Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc. LIBC=unknown
# We could probably try harder.
LIBC=gnu
set_cc_for_build set_cc_for_build
cat <<-EOF > "$dummy.c" cat <<-EOF > "$dummy.c"
@ -149,16 +147,30 @@ Linux|GNU|GNU/*)
LIBC=uclibc LIBC=uclibc
#elif defined(__dietlibc__) #elif defined(__dietlibc__)
LIBC=dietlibc LIBC=dietlibc
#elif defined(__GLIBC__)
LIBC=gnu
#else #else
#include <stdarg.h> #include <stdarg.h>
/* First heuristic to detect musl libc. */
#ifdef __DEFINED_va_list #ifdef __DEFINED_va_list
LIBC=musl LIBC=musl
#else
LIBC=gnu
#endif #endif
#endif #endif
EOF EOF
eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g')"
# Second heuristic to detect musl libc.
if [ "$LIBC" = unknown ] &&
command -v ldd >/dev/null &&
ldd --version 2>&1 | grep -q ^musl; then
LIBC=musl
fi
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
if [ "$LIBC" = unknown ]; then
LIBC=gnu
fi
;; ;;
esac esac
@ -177,19 +189,20 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# Note: NetBSD doesn't particularly care about the vendor # Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown". # portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch" sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ UNAME_MACHINE_ARCH=$( (uname -p 2>/dev/null || \
"/sbin/$sysctl" 2>/dev/null || \ "/sbin/$sysctl" 2>/dev/null || \
"/usr/sbin/$sysctl" 2>/dev/null || \ "/usr/sbin/$sysctl" 2>/dev/null || \
echo unknown)` echo unknown))
case "$UNAME_MACHINE_ARCH" in case "$UNAME_MACHINE_ARCH" in
aarch64eb) machine=aarch64_be-unknown ;;
armeb) machine=armeb-unknown ;; armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;; arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;; sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;; sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;; sh5el) machine=sh5le-unknown ;;
earmv*) earmv*)
arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` arch=$(echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,')
endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` endian=$(echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p')
machine="${arch}${endian}"-unknown machine="${arch}${endian}"-unknown
;; ;;
*) machine="$UNAME_MACHINE_ARCH"-unknown ;; *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
@ -220,7 +233,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
case "$UNAME_MACHINE_ARCH" in case "$UNAME_MACHINE_ARCH" in
earm*) earm*)
expr='s/^earmv[0-9]/-eabi/;s/eb$//' expr='s/^earmv[0-9]/-eabi/;s/eb$//'
abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` abi=$(echo "$UNAME_MACHINE_ARCH" | sed -e "$expr")
;; ;;
esac esac
# The OS release # The OS release
@ -233,7 +246,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
release='-gnu' release='-gnu'
;; ;;
*) *)
release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` release=$(echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2)
;; ;;
esac esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
@ -242,15 +255,15 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo "$machine-${os}${release}${abi-}" echo "$machine-${os}${release}${abi-}"
exit ;; exit ;;
*:Bitrig:*:*) *:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` UNAME_MACHINE_ARCH=$(arch | sed 's/Bitrig.//')
echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
exit ;; exit ;;
*:OpenBSD:*:*) *:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` UNAME_MACHINE_ARCH=$(arch | sed 's/OpenBSD.//')
echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
exit ;; exit ;;
*:LibertyBSD:*:*) *:LibertyBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` UNAME_MACHINE_ARCH=$(arch | sed 's/^.*BSD\.//')
echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
exit ;; exit ;;
*:MidnightBSD:*:*) *:MidnightBSD:*:*)
@ -286,17 +299,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
alpha:OSF1:*:*) alpha:OSF1:*:*)
case $UNAME_RELEASE in case $UNAME_RELEASE in
*4.0) *4.0)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $3}')
;; ;;
*5.*) *5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` UNAME_RELEASE=$(/usr/sbin/sizer -v | awk '{print $4}')
;; ;;
esac esac
# According to Compaq, /usr/sbin/psrinfo has been available on # According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that # OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU # covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0. # types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` ALPHA_CPU_TYPE=$(/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1)
case "$ALPHA_CPU_TYPE" in case "$ALPHA_CPU_TYPE" in
"EV4 (21064)") "EV4 (21064)")
UNAME_MACHINE=alpha ;; UNAME_MACHINE=alpha ;;
@ -334,7 +347,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# A Tn.n version is a released field test version. # A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel. # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r. # 1.2 uses "1.2" for uname -r.
echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" 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. # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$? exitcode=$?
trap '' 0 trap '' 0
@ -368,7 +381,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
exit ;; exit ;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then if test "$( (/bin/universe) 2>/dev/null)" = att ; then
echo pyramid-pyramid-sysv3 echo pyramid-pyramid-sysv3
else else
echo pyramid-pyramid-bsd echo pyramid-pyramid-bsd
@ -381,17 +394,17 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
echo sparc-icl-nx6 echo sparc-icl-nx6
exit ;; exit ;;
DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
case `/usr/bin/uname -p` in case $(/usr/bin/uname -p) in
sparc) echo sparc-icl-nx7; exit ;; sparc) echo sparc-icl-nx7; exit ;;
esac ;; esac ;;
s390x:SunOS:*:*) s390x:SunOS:*:*)
echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" echo "$UNAME_MACHINE"-ibm-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
exit ;; exit ;;
sun4H:SunOS:5.*:*) sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" echo sparc-hal-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;; exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" echo sparc-sun-solaris2"$(echo "$UNAME_RELEASE" | sed -e 's/[^.]*//')"
exit ;; exit ;;
i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
echo i386-pc-auroraux"$UNAME_RELEASE" echo i386-pc-auroraux"$UNAME_RELEASE"
@ -410,30 +423,30 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
SUN_ARCH=x86_64 SUN_ARCH=x86_64
fi fi
fi fi
echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" echo "$SUN_ARCH"-pc-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;; exit ;;
sun4*:SunOS:6*:*) sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize # According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but # SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4. # it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" echo sparc-sun-solaris3"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;; exit ;;
sun4*:SunOS:*:*) sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in case "$(/usr/bin/arch -k)" in
Series*|S4*) Series*|S4*)
UNAME_RELEASE=`uname -v` UNAME_RELEASE=$(uname -v)
;; ;;
esac esac
# Japanese Language versions have a version number like `4.1.3-JL'. # Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" echo sparc-sun-sunos"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/')"
exit ;; exit ;;
sun3*:SunOS:*:*) sun3*:SunOS:*:*)
echo m68k-sun-sunos"$UNAME_RELEASE" echo m68k-sun-sunos"$UNAME_RELEASE"
exit ;; exit ;;
sun*:*:4.2BSD:*) sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` UNAME_RELEASE=$( (sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null)
test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
case "`/bin/arch`" in case "$(/bin/arch)" in
sun3) sun3)
echo m68k-sun-sunos"$UNAME_RELEASE" echo m68k-sun-sunos"$UNAME_RELEASE"
;; ;;
@ -513,8 +526,8 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
} }
EOF EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" && $CC_FOR_BUILD -o "$dummy" "$dummy.c" &&
dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && dummyarg=$(echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p') &&
SYSTEM_NAME=`"$dummy" "$dummyarg"` && SYSTEM_NAME=$("$dummy" "$dummyarg") &&
{ echo "$SYSTEM_NAME"; exit; } { echo "$SYSTEM_NAME"; exit; }
echo mips-mips-riscos"$UNAME_RELEASE" echo mips-mips-riscos"$UNAME_RELEASE"
exit ;; exit ;;
@ -541,7 +554,7 @@ EOF
exit ;; exit ;;
AViiON:dgux:*:*) AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures # DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p` UNAME_PROCESSOR=$(/usr/bin/uname -p)
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110 if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then then
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \ if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
@ -569,17 +582,17 @@ EOF
echo m68k-tektronix-bsd echo m68k-tektronix-bsd
exit ;; exit ;;
*:IRIX*:*:*) *:IRIX*:*:*)
echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" echo mips-sgi-irix"$(echo "$UNAME_RELEASE"|sed -e 's/-/_/g')"
exit ;; exit ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' exit ;; # Note that: echo "'$(uname -s)'" gives 'AIX '
i*86:AIX:*:*) i*86:AIX:*:*)
echo i386-ibm-aix echo i386-ibm-aix
exit ;; exit ;;
ia64:AIX:*:*) ia64:AIX:*:*)
if test -x /usr/bin/oslevel ; then if test -x /usr/bin/oslevel ; then
IBM_REV=`/usr/bin/oslevel` IBM_REV=$(/usr/bin/oslevel)
else else
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi fi
@ -599,7 +612,7 @@ EOF
exit(0); exit(0);
} }
EOF EOF
if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy")
then then
echo "$SYSTEM_NAME" echo "$SYSTEM_NAME"
else else
@ -612,15 +625,15 @@ EOF
fi fi
exit ;; exit ;;
*:AIX:*:[4567]) *:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` 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 if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000 IBM_ARCH=rs6000
else else
IBM_ARCH=powerpc IBM_ARCH=powerpc
fi fi
if test -x /usr/bin/lslpp ; then if test -x /usr/bin/lslpp ; then
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | IBM_REV=$(/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` awk -F: '{ print $3 }' | sed s/[0-9]*$/0/)
else else
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
fi fi
@ -648,14 +661,14 @@ EOF
echo m68k-hp-bsd4.4 echo m68k-hp-bsd4.4
exit ;; exit ;;
9000/[34678]??:HP-UX:*:*) 9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
case "$UNAME_MACHINE" in case "$UNAME_MACHINE" in
9000/31?) HP_ARCH=m68000 ;; 9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;; 9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9]) 9000/[678][0-9][0-9])
if test -x /usr/bin/getconf; then if test -x /usr/bin/getconf; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_cpu_version=$(/usr/bin/getconf SC_CPU_VERSION 2>/dev/null)
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` sc_kernel_bits=$(/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null)
case "$sc_cpu_version" in case "$sc_cpu_version" in
523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
@ -702,7 +715,7 @@ EOF
exit (0); exit (0);
} }
EOF EOF
(CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=$("$dummy")
test -z "$HP_ARCH" && HP_ARCH=hppa test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;; fi ;;
esac esac
@ -730,7 +743,7 @@ EOF
echo "$HP_ARCH"-hp-hpux"$HPUX_REV" echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
exit ;; exit ;;
ia64:HP-UX:*:*) ia64:HP-UX:*:*)
HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` HPUX_REV=$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//')
echo ia64-hp-hpux"$HPUX_REV" echo ia64-hp-hpux"$HPUX_REV"
exit ;; exit ;;
3050*:HI-UX:*:*) 3050*:HI-UX:*:*)
@ -760,7 +773,7 @@ EOF
exit (0); exit (0);
} }
EOF EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=$("$dummy") &&
{ echo "$SYSTEM_NAME"; exit; } { echo "$SYSTEM_NAME"; exit; }
echo unknown-hitachi-hiuxwe2 echo unknown-hitachi-hiuxwe2
exit ;; exit ;;
@ -829,14 +842,14 @@ EOF
echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
exit ;; exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` FUJITSU_PROC=$(uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` FUJITSU_REL=$(echo "$UNAME_RELEASE" | sed -e 's/ /_/')
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
5000:UNIX_System_V:4.*:*) 5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` FUJITSU_SYS=$(uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///')
FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` FUJITSU_REL=$(echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/')
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;; exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@ -849,25 +862,25 @@ EOF
echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
exit ;; exit ;;
arm:FreeBSD:*:*) arm:FreeBSD:*:*)
UNAME_PROCESSOR=`uname -p` UNAME_PROCESSOR=$(uname -p)
set_cc_for_build set_cc_for_build
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP | grep -q __ARM_PCS_VFP
then then
echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabi echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabi
else else
echo "${UNAME_PROCESSOR}"-unknown-freebsd"`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`"-gnueabihf echo "${UNAME_PROCESSOR}"-unknown-freebsd"$(echo ${UNAME_RELEASE}|sed -e 's/[-(].*//')"-gnueabihf
fi fi
exit ;; exit ;;
*:FreeBSD:*:*) *:FreeBSD:*:*)
UNAME_PROCESSOR=`/usr/bin/uname -p` UNAME_PROCESSOR=$(/usr/bin/uname -p)
case "$UNAME_PROCESSOR" in case "$UNAME_PROCESSOR" in
amd64) amd64)
UNAME_PROCESSOR=x86_64 ;; UNAME_PROCESSOR=x86_64 ;;
i386) i386)
UNAME_PROCESSOR=i586 ;; UNAME_PROCESSOR=i586 ;;
esac esac
echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" echo "$UNAME_PROCESSOR"-unknown-freebsd"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
exit ;; exit ;;
i*:CYGWIN*:*) i*:CYGWIN*:*)
echo "$UNAME_MACHINE"-pc-cygwin echo "$UNAME_MACHINE"-pc-cygwin
@ -903,15 +916,15 @@ EOF
echo x86_64-pc-cygwin echo x86_64-pc-cygwin
exit ;; exit ;;
prep*:SunOS:5.*:*) prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" echo powerpcle-unknown-solaris2"$(echo "$UNAME_RELEASE"|sed -e 's/[^.]*//')"
exit ;; exit ;;
*:GNU:*:*) *:GNU:*:*)
# the GNU system # 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-$LIBC$(echo "$UNAME_RELEASE"|sed -e 's,/.*$,,')"
exit ;; exit ;;
*:GNU/*:*:*) *:GNU/*:*:*)
# other systems with GNU libc and userland # other systems with GNU libc and userland
echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" echo "$UNAME_MACHINE-unknown-$(echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]")$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')-$LIBC"
exit ;; exit ;;
*:Minix:*:*) *:Minix:*:*)
echo "$UNAME_MACHINE"-unknown-minix echo "$UNAME_MACHINE"-unknown-minix
@ -924,7 +937,7 @@ EOF
echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
exit ;; exit ;;
alpha:Linux:*:*) alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in case $(sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null) in
EV5) UNAME_MACHINE=alphaev5 ;; EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;; EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;; PCA56) UNAME_MACHINE=alphapca56 ;;
@ -1033,7 +1046,7 @@ EOF
#endif #endif
#endif #endif
EOF EOF
eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`" eval "$($CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI')"
test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; } test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
;; ;;
mips64el:Linux:*:*) mips64el:Linux:*:*)
@ -1053,7 +1066,7 @@ EOF
exit ;; exit ;;
parisc:Linux:*:* | hppa:Linux:*:*) parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level # Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in case $(grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2) in
PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
*) echo hppa-unknown-linux-"$LIBC" ;; *) echo hppa-unknown-linux-"$LIBC" ;;
@ -1143,7 +1156,7 @@ EOF
echo "$UNAME_MACHINE"-pc-msdosdjgpp echo "$UNAME_MACHINE"-pc-msdosdjgpp
exit ;; exit ;;
i*86:*:4.*:*) i*86:*:4.*:*)
UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` UNAME_REL=$(echo "$UNAME_RELEASE" | sed 's/\/MP$//')
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
else else
@ -1152,7 +1165,7 @@ EOF
exit ;; exit ;;
i*86:*:5:[678]*) 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 case $(/bin/uname -X | grep "^Machine") in
*486*) UNAME_MACHINE=i486 ;; *486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;; *Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
@ -1161,10 +1174,10 @@ EOF
exit ;; exit ;;
i*86:*:3.2:*) i*86:*:3.2:*)
if test -f /usr/options/cb.name; then if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` UNAME_REL=$(sed -n 's/.*Version //p' </usr/options/cb.name)
echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL" echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
elif /bin/uname -X 2>/dev/null >/dev/null ; then elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` UNAME_REL=$( (/bin/uname -X|grep Release|sed -e 's/.*= //'))
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586 && UNAME_MACHINE=i586
@ -1214,7 +1227,7 @@ EOF
3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
OS_REL='' OS_REL=''
test -r /etc/.relid \ test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /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 \ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; } && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@ -1225,7 +1238,7 @@ EOF
NCR*:*:4.2:* | MPRAS*:*:4.2:*) NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3' OS_REL='.3'
test -r /etc/.relid \ test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /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 \ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4.3"$OS_REL"; exit; } && { echo i486-ncr-sysv4.3"$OS_REL"; exit; }
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
@ -1258,7 +1271,7 @@ EOF
exit ;; exit ;;
*:SINIX-*:*:*) *:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null` UNAME_MACHINE=$( (uname -p) 2>/dev/null)
echo "$UNAME_MACHINE"-sni-sysv4 echo "$UNAME_MACHINE"-sni-sysv4
else else
echo ns32k-sni-sysv echo ns32k-sni-sysv
@ -1344,7 +1357,7 @@ EOF
echo aarch64-apple-darwin"$UNAME_RELEASE" echo aarch64-apple-darwin"$UNAME_RELEASE"
exit ;; exit ;;
*:Darwin:*:*) *:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` UNAME_PROCESSOR=$(uname -p)
case $UNAME_PROCESSOR in case $UNAME_PROCESSOR in
unknown) UNAME_PROCESSOR=powerpc ;; unknown) UNAME_PROCESSOR=powerpc ;;
esac esac
@ -1381,7 +1394,7 @@ EOF
echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
exit ;; exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*) *:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p` UNAME_PROCESSOR=$(uname -p)
if test "$UNAME_PROCESSOR" = x86; then if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386 UNAME_PROCESSOR=i386
UNAME_MACHINE=pc UNAME_MACHINE=pc
@ -1449,10 +1462,10 @@ EOF
echo mips-sei-seiux"$UNAME_RELEASE" echo mips-sei-seiux"$UNAME_RELEASE"
exit ;; exit ;;
*:DragonFly:*:*) *:DragonFly:*:*)
echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" echo "$UNAME_MACHINE"-unknown-dragonfly"$(echo "$UNAME_RELEASE"|sed -e 's/[-(].*//')"
exit ;; exit ;;
*:*VMS:*:*) *:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null` UNAME_MACHINE=$( (uname -p) 2>/dev/null)
case "$UNAME_MACHINE" in case "$UNAME_MACHINE" in
A*) echo alpha-dec-vms ; exit ;; A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;;
@ -1462,7 +1475,7 @@ EOF
echo i386-pc-xenix echo i386-pc-xenix
exit ;; exit ;;
i*86:skyos:*:*) i*86:skyos:*:*)
echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" echo "$UNAME_MACHINE"-pc-skyos"$(echo "$UNAME_RELEASE" | sed -e 's/ .*$//')"
exit ;; exit ;;
i*86:rdos:*:*) i*86:rdos:*:*)
echo "$UNAME_MACHINE"-pc-rdos echo "$UNAME_MACHINE"-pc-rdos
@ -1520,7 +1533,7 @@ main ()
#define __ARCHITECTURE__ "m68k" #define __ARCHITECTURE__ "m68k"
#endif #endif
int version; int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; version=$( (hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null);
if (version < 4) if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else else
@ -1612,7 +1625,7 @@ main ()
} }
EOF EOF
$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`$dummy` && $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=$($dummy) &&
{ echo "$SYSTEM_NAME"; exit; } { echo "$SYSTEM_NAME"; exit; }
# Apollos put the system type in the environment. # Apollos put the system type in the environment.
@ -1637,14 +1650,14 @@ This script (version $timestamp), has failed to recognize the
operating system you are using. If your script is old, overwrite *all* operating system you are using. If your script is old, overwrite *all*
copies of config.guess and config.sub with the latest versions from: copies of config.guess and config.sub with the latest versions from:
https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
and and
https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
EOF EOF
year=`echo $timestamp | sed 's,-.*,,'` year=$(echo $timestamp | sed 's,-.*,,')
# shellcheck disable=SC2003 # shellcheck disable=SC2003
if test "`expr "\`date +%Y\`" - "$year"`" -lt 3 ; then if test "$(expr "$(date +%Y)" - "$year")" -lt 3 ; then
cat >&2 <<EOF cat >&2 <<EOF
If $0 has already been updated, send the following data and any If $0 has already been updated, send the following data and any
@ -1653,20 +1666,20 @@ provide the necessary information to handle your system.
config.guess timestamp = $timestamp config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -m = $( (uname -m) 2>/dev/null || echo unknown)
uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -r = $( (uname -r) 2>/dev/null || echo unknown)
uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -s = $( (uname -s) 2>/dev/null || echo unknown)
uname -v = `(uname -v) 2>/dev/null || echo unknown` uname -v = $( (uname -v) 2>/dev/null || echo unknown)
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /usr/bin/uname -p = $( (/usr/bin/uname -p) 2>/dev/null)
/bin/uname -X = `(/bin/uname -X) 2>/dev/null` /bin/uname -X = $( (/bin/uname -X) 2>/dev/null)
hostinfo = `(hostinfo) 2>/dev/null` hostinfo = $( (hostinfo) 2>/dev/null)
/bin/universe = `(/bin/universe) 2>/dev/null` /bin/universe = $( (/bin/universe) 2>/dev/null)
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /usr/bin/arch -k = $( (/usr/bin/arch -k) 2>/dev/null)
/bin/arch = `(/bin/arch) 2>/dev/null` /bin/arch = $( (/bin/arch) 2>/dev/null)
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/bin/oslevel = $( (/usr/bin/oslevel) 2>/dev/null)
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` /usr/convex/getsysinfo = $( (/usr/convex/getsysinfo) 2>/dev/null)
UNAME_MACHINE = "$UNAME_MACHINE" UNAME_MACHINE = "$UNAME_MACHINE"
UNAME_RELEASE = "$UNAME_RELEASE" UNAME_RELEASE = "$UNAME_RELEASE"

View File

@ -2,7 +2,7 @@
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright 1992-2020 Free Software Foundation, Inc. # Copyright 1992-2020 Free Software Foundation, Inc.
timestamp='2020-09-08' timestamp='2020-12-02'
# This file is free software; you can redistribute it and/or modify it # 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 # under the terms of the GNU General Public License as published by
@ -33,7 +33,7 @@ timestamp='2020-09-08'
# Otherwise, we print the canonical config type on stdout and succeed. # Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from: # You can get the latest version of this script from:
# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
# This file is supposed to be the same for all GNU packages # This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases # and recognize all the CPU types, system types and aliases
@ -50,7 +50,7 @@ timestamp='2020-09-08'
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification. # It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'` me=$(echo "$0" | sed -e 's,.*/,,')
usage="\ usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
@ -769,22 +769,22 @@ case $basic_machine in
vendor=hp vendor=hp
;; ;;
i*86v32) i*86v32)
cpu=`echo "$1" | sed -e 's/86.*/86/'` cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc vendor=pc
basic_os=sysv32 basic_os=sysv32
;; ;;
i*86v4*) i*86v4*)
cpu=`echo "$1" | sed -e 's/86.*/86/'` cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc vendor=pc
basic_os=sysv4 basic_os=sysv4
;; ;;
i*86v) i*86v)
cpu=`echo "$1" | sed -e 's/86.*/86/'` cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc vendor=pc
basic_os=sysv basic_os=sysv
;; ;;
i*86sol2) i*86sol2)
cpu=`echo "$1" | sed -e 's/86.*/86/'` cpu=$(echo "$1" | sed -e 's/86.*/86/')
vendor=pc vendor=pc
basic_os=solaris2 basic_os=solaris2
;; ;;
@ -917,7 +917,7 @@ case $basic_machine in
;; ;;
leon-*|leon[3-9]-*) leon-*|leon[3-9]-*)
cpu=sparc cpu=sparc
vendor=`echo "$basic_machine" | sed 's/-.*//'` vendor=$(echo "$basic_machine" | sed 's/-.*//')
;; ;;
*-*) *-*)
@ -1084,7 +1084,7 @@ case $cpu-$vendor in
cpu=mipsisa64sb1el cpu=mipsisa64sb1el
;; ;;
sh5e[lb]-*) sh5e[lb]-*)
cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'` cpu=$(echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/')
;; ;;
spur-*) spur-*)
cpu=spur cpu=spur
@ -1102,7 +1102,7 @@ case $cpu-$vendor in
cpu=x86_64 cpu=x86_64
;; ;;
xscale-* | xscalee[bl]-*) xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'` cpu=$(echo "$cpu" | sed 's/^xscale/arm/')
;; ;;
arm64-*) arm64-*)
cpu=aarch64 cpu=aarch64
@ -1241,6 +1241,7 @@ case $cpu-$vendor in
| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
| spu \ | spu \
| tahoe \ | tahoe \
| thumbv7* \
| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \ | tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
| tron \ | tron \
| ubicom32 \ | ubicom32 \
@ -1286,11 +1287,15 @@ then
case $basic_os in case $basic_os in
gnu/linux*) gnu/linux*)
kernel=linux kernel=linux
os=`echo $basic_os | sed -e 's|gnu/linux|gnu|'` os=$(echo $basic_os | sed -e 's|gnu/linux|gnu|')
;;
os2-emx)
kernel=os2
os=$(echo $basic_os | sed -e 's|os2-emx|emx|')
;; ;;
nto-qnx*) nto-qnx*)
kernel=nto kernel=nto
os=`echo $basic_os | sed -e 's|nto-qnx|qnx|'` os=$(echo $basic_os | sed -e 's|nto-qnx|qnx|')
;; ;;
*-*) *-*)
# shellcheck disable=SC2162 # shellcheck disable=SC2162
@ -1301,11 +1306,11 @@ EOF
# Default OS when just kernel was specified # Default OS when just kernel was specified
nto*) nto*)
kernel=nto kernel=nto
os=`echo $basic_os | sed -e 's|nto|qnx|'` os=$(echo $basic_os | sed -e 's|nto|qnx|')
;; ;;
linux*) linux*)
kernel=linux kernel=linux
os=`echo $basic_os | sed -e 's|linux|gnu|'` os=$(echo $basic_os | sed -e 's|linux|gnu|')
;; ;;
*) *)
kernel= kernel=
@ -1326,7 +1331,7 @@ case $os in
os=cnk os=cnk
;; ;;
solaris1 | solaris1.*) solaris1 | solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'` os=$(echo $os | sed -e 's|solaris1|sunos4|')
;; ;;
solaris) solaris)
os=solaris2 os=solaris2
@ -1355,7 +1360,7 @@ case $os in
os=sco3.2v4 os=sco3.2v4
;; ;;
sco3.2.[4-9]*) sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` os=$(echo $os | sed -e 's/sco3.2./sco3.2v/')
;; ;;
sco*v* | scout) sco*v* | scout)
# Don't match below # Don't match below
@ -1385,7 +1390,7 @@ case $os in
os=lynxos os=lynxos
;; ;;
mac[0-9]*) mac[0-9]*)
os=`echo "$os" | sed -e 's|mac|macos|'` os=$(echo "$os" | sed -e 's|mac|macos|')
;; ;;
opened*) opened*)
os=openedition os=openedition
@ -1394,10 +1399,10 @@ case $os in
os=os400 os=os400
;; ;;
sunos5*) sunos5*)
os=`echo "$os" | sed -e 's|sunos5|solaris2|'` os=$(echo "$os" | sed -e 's|sunos5|solaris2|')
;; ;;
sunos6*) sunos6*)
os=`echo "$os" | sed -e 's|sunos6|solaris3|'` os=$(echo "$os" | sed -e 's|sunos6|solaris3|')
;; ;;
wince*) wince*)
os=wince os=wince
@ -1431,7 +1436,7 @@ case $os in
;; ;;
# Preserve the version number of sinix5. # Preserve the version number of sinix5.
sinix5.*) sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'` os=$(echo $os | sed -e 's|sinix|sysv|')
;; ;;
sinix*) sinix*)
os=sysv4 os=sysv4
@ -1716,7 +1721,7 @@ case $os in
| skyos* | haiku* | rdos* | toppers* | drops* | es* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* ) | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx*)
;; ;;
# This one is extra strict with allowed versions # This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*) sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@ -1747,6 +1752,8 @@ case $kernel-$os in
;; ;;
nto-qnx*) nto-qnx*)
;; ;;
os2-emx)
;;
*-eabi* | *-gnueabi*) *-eabi* | *-gnueabi*)
;; ;;
-*) -*)

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.12.0. # Generated by GNU Autoconf 2.69 for unbound 1.13.0.
# #
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>. # Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
# #
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='unbound' PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound' PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.12.0' PACKAGE_VERSION='1.13.0'
PACKAGE_STRING='unbound 1.12.0' PACKAGE_STRING='unbound 1.13.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL='' PACKAGE_URL=''
@ -1459,7 +1459,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures unbound 1.12.0 to adapt to many kinds of systems. \`configure' configures unbound 1.13.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1524,7 +1524,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.12.0:";; short | recursive ) echo "Configuration of unbound 1.13.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1752,7 +1752,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
unbound configure 1.12.0 unbound configure 1.13.0
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -2461,7 +2461,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.12.0, which was It was created by unbound $as_me 1.13.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2811,13 +2811,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1 UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=12 UNBOUND_VERSION_MINOR=13
UNBOUND_VERSION_MICRO=0 UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=10 LIBUNBOUND_REVISION=11
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -2895,6 +2895,7 @@ LIBUNBOUND_AGE=1
# 1.10.1 had 9:8:1 # 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1 # 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1 # 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -14728,7 +14729,7 @@ $as_echo "no" >&6; }
fi fi
# Checks for header files. # Checks for header files.
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h net/if.h for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h
do : do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
@ -14742,6 +14743,34 @@ fi
done done
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
for ac_header in net/if.h
do :
ac_fn_c_check_header_compile "$LINENO" "net/if.h" "ac_cv_header_net_if_h" "
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
"
if test "x$ac_cv_header_net_if_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NET_IF_H 1
_ACEOF
fi
done
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
for ac_header in TargetConditionals.h for ac_header in TargetConditionals.h
@ -21686,7 +21715,7 @@ _ACEOF
version=1.12.0 version=1.13.0
date=`date +'%b %e, %Y'` date=`date +'%b %e, %Y'`
@ -22205,7 +22234,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by unbound $as_me 1.12.0, which was This file was extended by unbound $as_me 1.13.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -22271,7 +22300,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
unbound config.status 1.12.0 unbound config.status 1.13.0
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -10,7 +10,7 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing # must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[12]) m4_define([VERSION_MINOR],[13])
m4_define([VERSION_MICRO],[0]) m4_define([VERSION_MICRO],[0])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound) AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
@ -18,7 +18,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=10 LIBUNBOUND_REVISION=11
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -96,6 +96,7 @@ LIBUNBOUND_AGE=1
# 1.10.1 had 9:8:1 # 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1 # 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1 # 1.12.0 had 9:10:1
# 1.13.0 had 9:11:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -399,7 +400,23 @@ ACX_LIBTOOL_C_ONLY
PKG_PROG_PKG_CONFIG PKG_PROG_PKG_CONFIG
# Checks for header files. # Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h net/if.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h],,, [AC_INCLUDES_DEFAULT])
# net/if.h portability for Darwin see:
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
AC_CHECK_HEADERS([net/if.h],,, [
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
AC_CHECK_HEADERS([TargetConditionals.h]) AC_CHECK_HEADERS([TargetConditionals.h])

View File

@ -53,3 +53,5 @@ distribution but may be helpful.
lookups for downstream clients. lookups for downstream clients.
* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format, * drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
contributed by Andreas Schulze. contributed by Andreas Schulze.
* metrics.awk: awk script that can convert unbound-control stats to
Prometheus metrics format output.

View File

@ -0,0 +1,180 @@
# read output of unbound-control stats
# and output prometheus metrics style output.
# use these options:
# server: extended-statistics: yes
# statistics-cumulative: no
# statistics-interval: 0
# remote-control: control-enable: yes
# Can use it like unbound-control stats | awk -f "metrics.awk"
BEGIN {
FS="=";
}
# everything like total.num.queries=value is put in val["total.num.queries"]
/^.*\..*=/ {
val[$1]=$2;
}
# print the output metrics
END {
print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
print "# TYPE unbound_hits_queries gauge"
print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
for (x=0; x<99; x++) {
if(val["thread" $x ".num.queries"] != "") {
print "unbound_hits_queries{type=\"thread" $x ".num.queries\"} " val["thread" $x ".num.queries"];
}
}
print "unbound_hits_queries{type=\"total.num.cachehits\"} " val["total.num.cachehits"];
print "unbound_hits_queries{type=\"total.num.prefetch\"} " val["total.num.prefetch"];
print "unbound_hits_queries{type=\"num.query.tcp\"} " val["num.query.tcp"];
print "unbound_hits_queries{type=\"num.query.tcpout\"} " val["num.query.tcpout"];
print "unbound_hits_queries{type=\"num.query.tls\"} " val["num.query.tls"];
print "unbound_hits_queries{type=\"num.query.tls.resume\"} " val["num.query.tls.resume"];
print "unbound_hits_queries{type=\"num.query.ipv6\"} " val["num.query.ipv6"];
print "unbound_hits_queries{type=\"unwanted.queries\"} " val["unwanted.queries"];
print ""
print "# HELP unbound_queue_queries Unbound requestlist size"
print "# TYPE unbound_queue_queries gauge"
print "unbound_queue_queries{type=\"total.requestlist.avg\"} " val["total.requestlist.avg"];
print "unbound_queue_queries{type=\"total.requestlist.max\"} " val["total.requestlist.max"];
print "unbound_queue_queries{type=\"total.requestlist.overwritten\"} " val["total.requestlist.overwritten"];
print "unbound_queue_queries{type=\"total.requestlist.exceeded\"} " val["total.requestlist.exceeded"];
print ""
print "# HELP unbound_memory_bytes Unbound memory usage"
print "# TYPE unbound_memory_bytes gauge"
print "unbound_memory_bytes{type=\"mem.cache.rrset\"} " val["mem.cache.rrset"];
print "unbound_memory_bytes{type=\"mem.cache.message\"} " val["mem.cache.message"];
print "unbound_memory_bytes{type=\"mem.mod.iterator\"} " val["mem.mod.iterator"];
if(val["mem.mod.validator"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.validator\"} " val["mem.mod.validator"];
}
if(val["mem.mod.respip"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.respip\"} " val["mem.mod.respip"];
}
if(val["mem.mod.subnet"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.subnet\"} " val["mem.mod.subnet"];
}
if(val["mem.mod.ipsecmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.ipsecmod\"} " val["mem.mod.ipsecmod"];
}
if(val["mem.mod.dynlibmod"] != "") {
print "unbound_memory_bytes{type=\"mem.mod.dynlibmod\"} " val["mem.mod.dynlibmod"];
}
print "unbound_memory_bytes{type=\"msg.cache.count\"} " val["msg.cache.count"];
print "unbound_memory_bytes{type=\"rrset.cache.count\"} " val["rrset.cache.count"];
print "unbound_memory_bytes{type=\"infra.cache.count\"} " val["infra.cache.count"];
print "unbound_memory_bytes{type=\"key.cache.count\"} " val["key.cache.count"];
print ""
print "# HELP unbound_by_type_queries Unbound DNS queries by type"
print "# TYPE unbound_by_type_queries gauge"
for(x in val) {
if(x ~ /^num.query.type./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_type_queries{type=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_class_queries Unbound DNS queries by class"
print "# TYPE unbound_by_class_queries gauge"
for(x in val) {
if(x ~ /^num.query.class./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_class_queries{class=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
print "# TYPE unbound_by_opcode_queries gauge"
for(x in val) {
if(x ~ /^num.query.opcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_opcode_queries{opcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
print "# TYPE unbound_by_rcode_queries gauge"
for(x in val) {
if(x ~ /^num.answer.rcode./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_rcode_queries{rcode=\"" a[4] "\"} " val[x];
}
}
}
print ""
print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
print "# TYPE unbound_by_flags_queries gauge"
for(x in val) {
if(x ~ /^num.query.flags./) {
if(val[x] != "") {
split(x, a, ".");
print "unbound_by_flags_queries{flag=\"" a[4] "\"} " val[x];
}
}
}
if(val["num.query.edns.present"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.present\"} " val["num.query.edns.present"];
}
if(val["num.query.edns.DO"] != "") {
print "unbound_by_flags_queries{flag=\"num.query.edns.DO\"} " val["num.query.edns.DO"];
}
print ""
print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
print "# TYPE unbound_histogram_seconds gauge"
print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
print "unbound_histogram_seconds{bucket=\"000000.000004.to.000000.000008\"} " val["histogram.000000.000004.to.000000.000008"];
print "unbound_histogram_seconds{bucket=\"000000.000008.to.000000.000016\"} " val["histogram.000000.000008.to.000000.000016"];
print "unbound_histogram_seconds{bucket=\"000000.000016.to.000000.000032\"} " val["histogram.000000.000016.to.000000.000032"];
print "unbound_histogram_seconds{bucket=\"000000.000032.to.000000.000064\"} " val["histogram.000000.000032.to.000000.000064"];
print "unbound_histogram_seconds{bucket=\"000000.000064.to.000000.000128\"} " val["histogram.000000.000064.to.000000.000128"];
print "unbound_histogram_seconds{bucket=\"000000.000128.to.000000.000256\"} " val["histogram.000000.000128.to.000000.000256"];
print "unbound_histogram_seconds{bucket=\"000000.000256.to.000000.000512\"} " val["histogram.000000.000256.to.000000.000512"];
print "unbound_histogram_seconds{bucket=\"000000.000512.to.000000.001024\"} " val["histogram.000000.000512.to.000000.001024"];
print "unbound_histogram_seconds{bucket=\"000000.001024.to.000000.002048\"} " val["histogram.000000.001024.to.000000.002048"];
print "unbound_histogram_seconds{bucket=\"000000.002048.to.000000.004096\"} " val["histogram.000000.002048.to.000000.004096"];
print "unbound_histogram_seconds{bucket=\"000000.004096.to.000000.008192\"} " val["histogram.000000.004096.to.000000.008192"];
print "unbound_histogram_seconds{bucket=\"000000.008192.to.000000.016384\"} " val["histogram.000000.008192.to.000000.016384"];
print "unbound_histogram_seconds{bucket=\"000000.016384.to.000000.032768\"} " val["histogram.000000.016384.to.000000.032768"];
print "unbound_histogram_seconds{bucket=\"000000.032768.to.000000.065536\"} " val["histogram.000000.032768.to.000000.065536"];
print "unbound_histogram_seconds{bucket=\"000000.065536.to.000000.131072\"} " val["histogram.000000.065536.to.000000.131072"];
print "unbound_histogram_seconds{bucket=\"000000.131072.to.000000.262144\"} " val["histogram.000000.131072.to.000000.262144"];
print "unbound_histogram_seconds{bucket=\"000000.262144.to.000000.524288\"} " val["histogram.000000.262144.to.000000.524288"];
print "unbound_histogram_seconds{bucket=\"000000.524288.to.000001.000000\"} " val["histogram.000000.524288.to.000001.000000"];
print "unbound_histogram_seconds{bucket=\"000001.000000.to.000002.000000\"} " val["histogram.000001.000000.to.000002.000000"];
print "unbound_histogram_seconds{bucket=\"000002.000000.to.000004.000000\"} " val["histogram.000002.000000.to.000004.000000"];
print "unbound_histogram_seconds{bucket=\"000004.000000.to.000008.000000\"} " val["histogram.000004.000000.to.000008.000000"];
print "unbound_histogram_seconds{bucket=\"000008.000000.to.000016.000000\"} " val["histogram.000008.000000.to.000016.000000"];
print "unbound_histogram_seconds{bucket=\"000016.000000.to.000032.000000\"} " val["histogram.000016.000000.to.000032.000000"];
print "unbound_histogram_seconds{bucket=\"000032.000000.to.000064.000000\"} " val["histogram.000032.000000.to.000064.000000"];
print "unbound_histogram_seconds{bucket=\"000064.000000.to.000128.000000\"} " val["histogram.000064.000000.to.000128.000000"];
print "unbound_histogram_seconds{bucket=\"000128.000000.to.000256.000000\"} " val["histogram.000128.000000.to.000256.000000"];
print "unbound_histogram_seconds{bucket=\"000256.000000.to.000512.000000\"} " val["histogram.000256.000000.to.000512.000000"];
print "unbound_histogram_seconds{bucket=\"000512.000000.to.001024.000000\"} " val["histogram.000512.000000.to.001024.000000"];
print "unbound_histogram_seconds{bucket=\"001024.000000.to.002048.000000\"} " val["histogram.001024.000000.to.002048.000000"];
print "unbound_histogram_seconds{bucket=\"002048.000000.to.004096.000000\"} " val["histogram.002048.000000.to.004096.000000"];
print "unbound_histogram_seconds{bucket=\"004096.000000.to.008192.000000\"} " val["histogram.004096.000000.to.008192.000000"];
print "unbound_histogram_seconds{bucket=\"008192.000000.to.016384.000000\"} " val["histogram.008192.000000.to.016384.000000"];
print "unbound_histogram_seconds{bucket=\"016384.000000.to.032768.000000\"} " val["histogram.016384.000000.to.032768.000000"];
print "unbound_histogram_seconds{bucket=\"032768.000000.to.065536.000000\"} " val["histogram.032768.000000.to.065536.000000"];
print "unbound_histogram_seconds{bucket=\"065536.000000.to.131072.000000\"} " val["histogram.065536.000000.to.131072.000000"];
print "unbound_histogram_seconds{bucket=\"131072.000000.to.262144.000000\"} " val["histogram.131072.000000.to.262144.000000"];
print "unbound_histogram_seconds{bucket=\"262144.000000.to.524288.000000\"} " val["histogram.262144.000000.to.524288.000000"];
print ""
}

View File

@ -66,7 +66,7 @@ ProtectSystem=strict
RuntimeDirectory=unbound RuntimeDirectory=unbound
ConfigurationDirectory=unbound ConfigurationDirectory=unbound
StateDirectory=unbound StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictRealtime=true RestrictRealtime=true
SystemCallArchitectures=native SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources

View File

@ -38,7 +38,7 @@ ProtectSystem=strict
RuntimeDirectory=unbound RuntimeDirectory=unbound
ConfigurationDirectory=unbound ConfigurationDirectory=unbound
StateDirectory=unbound StateDirectory=unbound
RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictRealtime=true RestrictRealtime=true
SystemCallArchitectures=native SystemCallArchitectures=native
SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources

View File

@ -291,7 +291,7 @@ daemon_init(void)
free(daemon); free(daemon);
return NULL; return NULL;
} }
if(!(daemon->env->edns_tags = edns_tags_create())) { if(!(daemon->env->edns_strings = edns_strings_create())) {
auth_zones_delete(daemon->env->auth_zones); auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl); acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl); tcl_list_delete(daemon->tcl);
@ -638,9 +638,9 @@ daemon_fork(struct daemon* daemon)
&daemon->use_rpz)) &daemon->use_rpz))
fatal_exit("auth_zones could not be setup"); fatal_exit("auth_zones could not be setup");
/* Set-up EDNS tags */ /* Set-up EDNS strings */
if(!edns_tags_apply_cfg(daemon->env->edns_tags, daemon->cfg)) if(!edns_strings_apply_cfg(daemon->env->edns_strings, daemon->cfg))
fatal_exit("Could not set up EDNS tags"); fatal_exit("Could not set up EDNS strings");
/* setup modules */ /* setup modules */
daemon_setup_modules(daemon); daemon_setup_modules(daemon);
@ -773,7 +773,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache); rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache); infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env); edns_known_options_delete(daemon->env);
edns_tags_delete(daemon->env->edns_tags); edns_strings_delete(daemon->env->edns_strings);
auth_zones_delete(daemon->env->auth_zones); auth_zones_delete(daemon->env->auth_zones);
} }
ub_randfree(daemon->rand); ub_randfree(daemon->rand);

View File

@ -337,22 +337,44 @@ readpid (const char* file)
/** write pid to file. /** write pid to file.
* @param pidfile: file name of pid file. * @param pidfile: file name of pid file.
* @param pid: pid to write to file. * @param pid: pid to write to file.
* @return false on failure
*/ */
static void static int
writepid (const char* pidfile, pid_t pid) writepid (const char* pidfile, pid_t pid)
{ {
FILE* f; int fd;
char pidbuf[32];
size_t count = 0;
snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long)pid);
if ((f = fopen(pidfile, "w")) == NULL ) { if((fd = open(pidfile, O_WRONLY | O_CREAT | O_TRUNC
#ifdef O_NOFOLLOW
| O_NOFOLLOW
#endif
, 0644)) == -1) {
log_err("cannot open pidfile %s: %s", log_err("cannot open pidfile %s: %s",
pidfile, strerror(errno)); pidfile, strerror(errno));
return; return 0;
} }
if(fprintf(f, "%lu\n", (unsigned long)pid) < 0) { while(count < strlen(pidbuf)) {
log_err("cannot write to pidfile %s: %s", ssize_t r = write(fd, pidbuf+count, strlen(pidbuf)-count);
pidfile, strerror(errno)); if(r == -1) {
if(errno == EAGAIN || errno == EINTR)
continue;
log_err("cannot write to pidfile %s: %s",
pidfile, strerror(errno));
close(fd);
return 0;
} else if(r == 0) {
log_err("cannot write any bytes to pidfile %s: "
"write returns 0 bytes written", pidfile);
close(fd);
return 0;
}
count += r;
} }
fclose(f); close(fd);
return 1;
} }
/** /**
@ -506,16 +528,17 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
/* write new pidfile (while still root, so can be outside chroot) */ /* write new pidfile (while still root, so can be outside chroot) */
#ifdef HAVE_KILL #ifdef HAVE_KILL
if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) { if(cfg->pidfile && cfg->pidfile[0] && need_pidfile) {
writepid(daemon->pidfile, getpid()); if(writepid(daemon->pidfile, getpid())) {
if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 && if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
pidinchroot) { pidinchroot) {
# ifdef HAVE_CHOWN # ifdef HAVE_CHOWN
if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) { if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
verbose(VERB_QUERY, "cannot chown %u.%u %s: %s", verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
(unsigned)cfg_uid, (unsigned)cfg_gid, (unsigned)cfg_uid, (unsigned)cfg_gid,
daemon->pidfile, strerror(errno)); daemon->pidfile, strerror(errno));
} }
# endif /* HAVE_CHOWN */ # endif /* HAVE_CHOWN */
}
} }
} }
#else #else

View File

@ -576,7 +576,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset, struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
struct reply_info** encode_repp, struct auth_zones* az) struct reply_info** encode_repp, struct auth_zones* az)
{ {
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
if(qinfo->qtype != LDNS_RR_TYPE_A && if(qinfo->qtype != LDNS_RR_TYPE_A &&
@ -1789,8 +1789,8 @@ worker_init(struct worker* worker, struct config_file *cfg,
? cfg->tcp_keepalive_timeout ? cfg->tcp_keepalive_timeout
: cfg->tcp_idle_timeout, : cfg->tcp_idle_timeout,
cfg->harden_large_queries, cfg->http_max_streams, cfg->harden_large_queries, cfg->http_max_streams,
cfg->http_endpoint, worker->daemon->tcl, cfg->http_endpoint, cfg->http_notls_downstream,
worker->daemon->listen_sslctx, worker->daemon->tcl, worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker); dtenv, worker_handle_request, worker);
if(!worker->front) { if(!worker->front) {
log_err("could not create listening sockets"); log_err("could not create listening sockets");
@ -1807,7 +1807,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
&worker_alloc_cleanup, worker, &worker_alloc_cleanup, worker,
cfg->do_udp || cfg->udp_upstream_without_downstream, cfg->do_udp || cfg->udp_upstream_without_downstream,
worker->daemon->connect_sslctx, cfg->delay_close, worker->daemon->connect_sslctx, cfg->delay_close,
cfg->tls_use_sni, dtenv); cfg->tls_use_sni, dtenv, cfg->udp_connect);
if(!worker->back) { if(!worker->back) {
log_err("could not create outgoing sockets"); log_err("could not create outgoing sockets");
worker_delete(worker); worker_delete(worker);

View File

@ -134,15 +134,13 @@ dt_create(struct config_file* cfg)
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] && if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) { (cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
char* p = fname_after_chroot(cfg->dnstap_socket_path, cfg, 1); char* p = cfg->dnstap_socket_path;
if(!p) { if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(p,
log_err("malloc failure"); cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
return NULL; p += strlen(cfg->chrootdir);
}
verbose(VERB_OPS, "attempting to connect to dnstap socket %s", verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
p); p);
check_socket_file(p); check_socket_file(p);
free(p);
} }
env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); env = (struct dt_env *) calloc(1, sizeof(struct dt_env));

View File

@ -341,15 +341,19 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
dtio->is_bidirectional = cfg->dnstap_bidirectional; dtio->is_bidirectional = cfg->dnstap_bidirectional;
if(dtio->upstream_is_unix) { if(dtio->upstream_is_unix) {
char* nm;
if(!cfg->dnstap_socket_path || if(!cfg->dnstap_socket_path ||
cfg->dnstap_socket_path[0]==0) { cfg->dnstap_socket_path[0]==0) {
log_err("dnstap setup: no dnstap-socket-path for " log_err("dnstap setup: no dnstap-socket-path for "
"socket connect"); "socket connect");
return 0; return 0;
} }
nm = cfg->dnstap_socket_path;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
nm += strlen(cfg->chrootdir);
free(dtio->socket_path); free(dtio->socket_path);
dtio->socket_path = fname_after_chroot(cfg->dnstap_socket_path, dtio->socket_path = strdup(nm);
cfg, 1);
if(!dtio->socket_path) { if(!dtio->socket_path) {
log_err("dnstap setup: malloc failure"); log_err("dnstap setup: malloc failure");
return 0; return 0;

View File

@ -1,3 +1,166 @@
30 November 2020: Wouter
- Fix assertion failure on double callback when iterator loses
interest in query at head of line that then has the tcp stream
not kept for reuse.
- tag for the 1.13.0rc4 release.
27 November 2020: Wouter
- Fix compile warning for type cast in http2_submit_dns_response.
- Fix when use free buffer to initialize rbtree for stream reuse.
- Fix compile warnings for windows.
- Fix compile warnings in rpz initialization.
- Fix contrib/metrics.awk for FreeBSD awk compatibility.
- tag for the 1.13.0rc3 release.
26 November 2020: Wouter
- Fix to omit UDP receive errors from log, if verbosity low.
These happen because of udp-connect.
- For #352: contrib/metrics.awk for Prometheus style metrics output.
- Fix that after failed read, the readagain cannot activate.
- Clear readagain upon decommission of pending tcp structure.
25 November 2020: Wouter
- with udp-connect ignore connection refused with UDP timeouts.
- Fix udp-connect on FreeBSD, do send calls on connected UDP socket.
- Better fix for reuse tree comparison for is-tls sockets. Where
the tree key identity is preserved after cleanup of the TLS state.
- Remove debug commands from reuse tests.
- Fix memory leak for edns client tag opcode config element.
- Attempt fix for libevent state in tcp reuse cases after a packet
is written.
- Fix readagain and writeagain callback functions for comm point
cleanup.
- tag for the 1.13.0rc2 release.
24 November 2020: Wouter
- Merge PR #283 : Stream reuse. This implements upstream stream
reuse for performing several queries over the same TCP or TLS
channel.
- set version of main branch to 1.13.0 for upcoming release.
- iana portlist updated.
- Fix one port unit test for udp-connect.
- tag for the 1.13.0rc1 release.
- Fix crash when TLS connection is closed prematurely, when
reuse tree comparison is not properly identical to insertion.
- Fix padding of struct regional for 32bit systems.
23 November 2020: George
- Merge PR #313 from Ralph Dolmans: Replace edns-client-tag with
edns-client-string option.
23 November 2020: Wouter
- Merge #351 from dvzrv: Add AF_NETLINK to set of allowed socket
address families.
- Fix #350: with the AF_NETLINK permission, to fix 1.12.0 error:
failed to list interfaces: getifaddrs: Address family not
supported by protocol.
- Fix #347: IP_DONTFRAG broken on Apple xcode 12.2.
- Option to toggle udp-connect, default is enabled.
- Fix for #303 CVE-2020-28935 : Fix that symlink does not interfere
with chown of pidfile.
- Further fix for it and retvalue 0 fix for it.
12 November 2020: Wouter
- Fix to connect() to UDP destinations, default turned on,
this lowers vulnerability to ICMP side channels.
- Retry for interfaces with unused ports if possible.
10 November 2020: Wouter
- Fix #341: fixing a possible memory leak.
- Fix memory leak after fix for possible memory leak failure.
- Fix #343: Fail to build --with-libnghttp2 with error: 'SSIZE_MAX'
undeclared.
27 October 2020: Wouter
- In man page note that tls-cert-bundle is read before permission
drop and chroot.
22 October 2020: Wouter
- Fix #333: Unbound Segmentation Fault w/ log_info Functions From
Python Mod.
- Fix that minimal-responses does not remove addresses from a priming
query response.
21 October 2020: George
- Fix #327: net/if.h check fails on some darwin versions; contribution by
Joshua Root.
- Fix #320: potential memory corruption due to size miscomputation upton
custom region alloc init.
21 October 2020: Wouter
- Merge PR #228 : infra-keep-probing option to probe hosts that are
down. Add infra-keep-probing: yes option. Hosts that are down are
probed more frequently.
With the option turned on, it probes about every 120 seconds,
eventually after exponential backoff, and that keeps that way. If
traffic keeps up for the domain. It probes with one at a time, eg.
one query is allowed to probe, other queries within that 120 second
interval are turned away.
19 October 2020: George
- Merge PR #324 from James Renken: Add modern X.509v3 extensions to
unbound-control TLS certificates.
- Fix for PR #324 to attach the x509v3 extensions to the client
certificate.
19 October 2020: Ralph
- local-zone regional allocations outside of chunk
19 October 2020: Wouter
- Fix that http settings have colon in set_option, for
http-endpoint, http-max-streams, http-query-buffer-size,
http-response-buffer-size, and http-nodelay.
- Fix memory leak of https port string when reading config.
- Fix #330: [Feature request] Add unencrypted DNS over HTTPS support.
This adds the option http-notls-downstream: yesno to change that,
and the dohclient test code has the -n option.
- Fix python documentation warning on functions.rst inplace_cb_reply.
- Fix dnstap test to wait for log timer to see if queries are logged.
- Log ip address when http session recv fails, eg. due to tls fail.
- Fix to set the tcp handler event toggle flag back to default when
the handler structure is reused.
- Clean the fix for out of order TCP processing limits on number
of queries. It was tested to work.
16 October 2020: Wouter
- Fix that the out of order TCP processing does not limit the
number of outstanding queries over a connection.
15 October 2020: George
- Fix that if there are reply callbacks for the given rcode, those
are called per reply and a new message created if that was modified
by the call.
- Pass the comm_reply information to the inplace_cb_reply* functions
during the mesh state and update the documentation on that.
15 October 2020: Wouter
- Merge PR #326 from netblue30: DoH: implement content-length
header field
- DoH content length, simplify code, remove declaration after
statement and fix cast warning.
14 October 2020: Wouter
- Fix for python reply callback to see mesh state reply_list member,
it only removes it briefly for the commpoint call so that it does
not drop it and attempt to modify the reply list during reply.
- Fix that if there are on reply callbacks, those are called per
reply and a new message created if that was modified by the call.
- Free up auth zone parse region after use for lookup of host
13 October 2020: Wouter
- Fix #323: unbound testsuite fails on mock build in systemd-nspawn
if systemd support is build.
9 October 2020: Wouter
- Fix dnstap socket and the chroot not applied properly to the dnstap
socket path.
- Fix warning in libnss compile, nss_buf2dsa is not used without DSA.
8 October 2020: Wouter
- Tag for 1.12.0 release.
- Current repo is version 1.12.1 in development.
- Fix #319: potential memory leak on config failure, in rpz config.
1 October 2020: Wouter 1 October 2020: Wouter
- Current repo is version 1.12.0 for release. Tag for 1.12.0rc1. - Current repo is version 1.12.0 for release. Tag for 1.12.0rc1.

View File

@ -1,4 +1,4 @@
README for Unbound 1.12.0 README for Unbound 1.13.0
Copyright 2007 NLnet Labs Copyright 2007 NLnet Labs
http://unbound.net http://unbound.net

View File

@ -1,7 +1,7 @@
# #
# Example configuration file. # Example configuration file.
# #
# See unbound.conf(5) man page, version 1.12.0. # See unbound.conf(5) man page, version 1.13.0.
# #
# this is a comment. # this is a comment.
@ -161,6 +161,9 @@ server:
# msec to wait before close of port on timeout UDP. 0 disables. # msec to wait before close of port on timeout UDP. 0 disables.
# delay-close: 0 # delay-close: 0
# perform connect for UDP sockets to mitigate ICMP side channel.
# udp-connect: yes
# msec for waiting for an unknown server to reply. Increase if you # msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128. # are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376 # unknown-server-time-limit: 376
@ -192,6 +195,9 @@ server:
# minimum wait time for responses, increase if uplink is long. In msec. # minimum wait time for responses, increase if uplink is long. In msec.
# infra-cache-min-rtt: 50 # infra-cache-min-rtt: 50
# enable to make server probe down hosts more frequently.
# infra-keep-probing: no
# the number of slabs to use for the Infrastructure cache. # the number of slabs to use for the Infrastructure cache.
# the number of slabs must be a power of 2. # the number of slabs must be a power of 2.
# more slabs reduce lock contention, but fragment memory usage. # more slabs reduce lock contention, but fragment memory usage.
@ -788,6 +794,9 @@ server:
# service. # service.
# http-nodelay: yes # http-nodelay: yes
# Disable TLS for DNS-over-HTTP downstream service.
# http-notls-downstream: no
# DNS64 prefix. Must be specified when DNS64 is use. # DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4. # Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96 # dns64-prefix: 64:ff9b::0/96

View File

@ -1,4 +1,4 @@
.TH "libunbound" "3" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "libunbound" "3" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" libunbound.3 -- unbound library functions manual .\" libunbound.3 -- unbound library functions manual
.\" .\"
@ -44,7 +44,7 @@
.B ub_ctx_zone_remove, .B ub_ctx_zone_remove,
.B ub_ctx_data_add, .B ub_ctx_data_add,
.B ub_ctx_data_remove .B ub_ctx_data_remove
\- Unbound DNS validating resolver 1.12.0 functions. \- Unbound DNS validating resolver 1.13.0 functions.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B #include <unbound.h> .B #include <unbound.h>
.LP .LP

View File

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound-anchor" "8" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\" .\"

View File

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound-checkconf" "8" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound-checkconf.8 -- unbound configuration checker manual .\" unbound-checkconf.8 -- unbound configuration checker manual
.\" .\"

View File

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound-control" "8" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound-control.8 -- unbound remote control manual .\" unbound-control.8 -- unbound remote control manual
.\" .\"

View File

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound\-host" "1" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound-host.1 -- unbound DNS lookup utility .\" unbound-host.1 -- unbound DNS lookup utility
.\" .\"

View File

@ -1,4 +1,4 @@
.TH "unbound" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound" "8" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound.8 -- unbound manual .\" unbound.8 -- unbound manual
.\" .\"
@ -9,7 +9,7 @@
.\" .\"
.SH "NAME" .SH "NAME"
.B unbound .B unbound
\- Unbound DNS validating resolver 1.12.0. \- Unbound DNS validating resolver 1.13.0.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B unbound .B unbound
.RB [ \-h ] .RB [ \-h ]

View File

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0" .TH "unbound.conf" "5" "Dec 3, 2020" "NLnet Labs" "unbound 1.13.0"
.\" .\"
.\" unbound.conf.5 -- unbound.conf manual .\" unbound.conf.5 -- unbound.conf manual
.\" .\"
@ -274,6 +274,10 @@ eg. 1500 msec. When timeouts happen you need extra sockets, it checks
the ID and remote IP of packets, and unwanted packets are added to the the ID and remote IP of packets, and unwanted packets are added to the
unwanted packet counter. unwanted packet counter.
.TP .TP
.B udp\-connect: \fI<yes or no>
Perform connect for UDP sockets that mitigates ICMP side channel leakage.
Default is yes.
.TP
.B unknown\-server\-time\-limit: \fI<msec> .B unknown\-server\-time\-limit: \fI<msec>
The wait time in msec for waiting for an unknown server to reply. The wait time in msec for waiting for an unknown server to reply.
Increase this if you are behind a slow satellite link, to eg. 1128. Increase this if you are behind a slow satellite link, to eg. 1128.
@ -382,6 +386,12 @@ Lower limit for dynamic retransmit timeout calculation in infrastructure
cache. Default is 50 milliseconds. Increase this value if using forwarders cache. Default is 50 milliseconds. Increase this value if using forwarders
needing more time to do recursive name resolution. needing more time to do recursive name resolution.
.TP .TP
.B infra\-keep\-probing: \fI<yes or no>
If enabled the server keeps probing hosts that are down, in the one probe
at a time regime. Default is no. Hosts that are down, eg. they did
not respond during the one probe at a time period, are marked as down and
it may take \fBinfra\-host\-ttl\fR time to get probed again.
.TP
.B define\-tag: \fI<"list of tags"> .B define\-tag: \fI<"list of tags">
Define the tags that can be used with local\-zone and access\-control. Define the tags that can be used with local\-zone and access\-control.
Enclose the list between quotes ("") and put spaces between tags. Enclose the list between quotes ("") and put spaces between tags.
@ -516,7 +526,8 @@ Alternate syntax for \fBtls\-port\fR.
If null or "", no file is used. Set it to the certificate bundle file, If null or "", no file is used. Set it to the certificate bundle file,
for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used for example "/etc/pki/tls/certs/ca\-bundle.crt". These certificates are used
for authenticating connections made to outside peers. For example auth\-zone for authenticating connections made to outside peers. For example auth\-zone
urls, and also DNS over TLS connections. urls, and also DNS over TLS connections. It is read at start up before
permission drop and chroot.
.TP .TP
.B ssl\-cert\-bundle: \fI<file> .B ssl\-cert\-bundle: \fI<file>
Alternate syntax for \fBtls\-cert\-bundle\fR. Alternate syntax for \fBtls\-cert\-bundle\fR.
@ -587,6 +598,10 @@ megabytes or gigabytes (1024*1024 bytes in a megabyte).
Set TCP_NODELAY socket option on sockets used to provide DNS-over-HTTPS service. Set TCP_NODELAY socket option on sockets used to provide DNS-over-HTTPS service.
Ignored if the option is not available. Default is yes. Ignored if the option is not available. Default is yes.
.TP .TP
.B http\-notls\-downstream: \fI<yes or no>
Disable use of TLS for the downstream DNS-over-HTTP connections. Useful for
local back end servers. Default is no.
.TP
.B use\-systemd: \fI<yes or no> .B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation. Enable or disable systemd socket activation.
Default is no. Default is no.
@ -1535,15 +1550,15 @@ Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers. option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5 .TP 5
.B edns\-client\-tag: \fI<IP netblock> <tag data> .B edns\-client\-string: \fI<IP netblock> <string>
Include an edns-client-tag option in queries with destination address matching Include an EDNS0 option containing configured ascii string in queries with
the configured IP netblock. This configuration option can be used multiple destination address matching the configured IP netblock. This configuration
times. The most specific match will be used. The tag data is configured in option can be used multiple times. The most specific match will be used.
decimal format, from 0 to 65535.
.TP 5 .TP 5
.B edns\-client\-tag\-opcode: \fI<opcode> .B edns\-client\-string\-opcode: \fI<opcode>
EDNS0 option code for the edns-client-tag option, from 0 to 65535. Default is EDNS0 option code for the \fIedns\-client\-string\fR option, from 0 to 65535.
16, as assigned by IANA. A value from the `Reserved for Local/Experimental` range (65001-65534) should
be used. Default is 65001.
.SS "Remote Control Options" .SS "Remote Control Options"
In the In the
.B remote\-control: .B remote\-control:

View File

@ -80,7 +80,7 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL; return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz)) if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
return UB_INITFAIL; return UB_INITFAIL;
if(!edns_tags_apply_cfg(ctx->env->edns_tags, cfg)) if(!edns_strings_apply_cfg(ctx->env->edns_strings, cfg))
return UB_INITFAIL; return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size, if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) { cfg->msg_cache_slabs)) {

View File

@ -154,8 +154,8 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
ctx->env->edns_tags = edns_tags_create(); ctx->env->edns_strings = edns_strings_create();
if(!ctx->env->edns_tags) { if(!ctx->env->edns_strings) {
auth_zones_delete(ctx->env->auth_zones); auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
@ -186,7 +186,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags); edns_strings_delete(ctx->env->edns_strings);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
errno = e; errno = e;
@ -199,7 +199,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env); modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags); edns_strings_delete(ctx->env->edns_strings);
free(ctx->env); free(ctx->env);
free(ctx); free(ctx);
errno = e; errno = e;
@ -338,7 +338,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache); infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg); config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env); edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags); edns_strings_delete(ctx->env->edns_strings);
auth_zones_delete(ctx->env->auth_zones); auth_zones_delete(ctx->env->auth_zones);
free(ctx->env); free(ctx->env);
} }

View File

@ -238,7 +238,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
ports, numports, cfg->unwanted_threshold, ports, numports, cfg->unwanted_threshold,
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w, cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx, cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
cfg->delay_close, cfg->tls_use_sni, NULL); cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect);
w->env->outnet = w->back; w->env->outnet = w->back;
if(!w->is_bg || w->is_bg_thread) { if(!w->is_bg || w->is_bg_thread) {
lock_basic_unlock(&ctx->cfglock); lock_basic_unlock(&ctx->cfglock);

View File

@ -914,7 +914,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
int ret = 1; int ret = 1;
struct ub_packed_rrset_key* redirect_rrset = NULL; struct ub_packed_rrset_key* redirect_rrset = NULL;
struct rpz* r; struct rpz* r;
struct auth_zone* a; struct auth_zone* a = NULL;
struct ub_packed_rrset_key* data = NULL; struct ub_packed_rrset_key* data = NULL;
int rpz_used = 0; int rpz_used = 0;
int rpz_log = 0; int rpz_log = 0;
@ -1109,7 +1109,7 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
qstate->return_msg && qstate->return_msg->rep) { qstate->return_msg && qstate->return_msg->rep) {
struct reply_info* new_rep = qstate->return_msg->rep; struct reply_info* new_rep = qstate->return_msg->rep;
struct ub_packed_rrset_key* alias_rrset = NULL; struct ub_packed_rrset_key* alias_rrset = NULL;
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
if(!respip_rewrite_reply(&qstate->qinfo, if(!respip_rewrite_reply(&qstate->qinfo,
@ -1170,7 +1170,7 @@ respip_merge_cname(struct reply_info* base_rep,
struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */ struct ub_packed_rrset_key* alias_rrset = NULL; /* ditto */
uint16_t tgt_rcode; uint16_t tgt_rcode;
size_t i, j; size_t i, j;
struct respip_action_info actinfo = {0}; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
actinfo.action = respip_none; actinfo.action = respip_none;
/* If the query for the CNAME target would result in an unusual rcode, /* If the query for the CNAME target would result in an unusual rcode,

View File

@ -5387,6 +5387,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A"));
} }
} }
regional_free_all(temp);
} else { } else {
if(verbosity >= VERB_ALGO) { if(verbosity >= VERB_ALGO) {
char zname[255+1]; char zname[255+1];
@ -6444,6 +6445,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A"));
} }
} }
regional_free_all(temp);
} else { } else {
if(verbosity >= VERB_ALGO) { if(verbosity >= VERB_ALGO) {
char zname[255+1]; char zname[255+1];

View File

@ -244,6 +244,7 @@ infra_create(struct config_file* cfg)
return NULL; return NULL;
} }
infra->host_ttl = cfg->host_ttl; infra->host_ttl = cfg->host_ttl;
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit; infra_dp_ratelimit = cfg->ratelimit;
infra->domain_rates = slabhash_create(cfg->ratelimit_slabs, infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
INFRA_HOST_STARTSIZE, cfg->ratelimit_size, INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
@ -297,6 +298,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
if(!infra) if(!infra)
return infra_create(cfg); return infra_create(cfg);
infra->host_ttl = cfg->host_ttl; infra->host_ttl = cfg->host_ttl;
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit; infra_dp_ratelimit = cfg->ratelimit;
infra_ip_ratelimit = cfg->ip_ratelimit; infra_ip_ratelimit = cfg->ip_ratelimit;
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+ maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
@ -445,6 +447,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
if(e && ((struct infra_data*)e->data)->ttl < timenow) { if(e && ((struct infra_data*)e->data)->ttl < timenow) {
/* it expired, try to reuse existing entry */ /* it expired, try to reuse existing entry */
int old = ((struct infra_data*)e->data)->rtt.rto; int old = ((struct infra_data*)e->data)->rtt.rto;
time_t tprobe = ((struct infra_data*)e->data)->probedelay;
uint8_t tA = ((struct infra_data*)e->data)->timeout_A; uint8_t tA = ((struct infra_data*)e->data)->timeout_A;
uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA; uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA;
uint8_t tother = ((struct infra_data*)e->data)->timeout_other; uint8_t tother = ((struct infra_data*)e->data)->timeout_other;
@ -460,6 +463,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
if(old >= USEFUL_SERVER_TOP_TIMEOUT) { if(old >= USEFUL_SERVER_TOP_TIMEOUT) {
((struct infra_data*)e->data)->rtt.rto ((struct infra_data*)e->data)->rtt.rto
= USEFUL_SERVER_TOP_TIMEOUT; = USEFUL_SERVER_TOP_TIMEOUT;
((struct infra_data*)e->data)->probedelay = tprobe;
((struct infra_data*)e->data)->timeout_A = tA; ((struct infra_data*)e->data)->timeout_A = tA;
((struct infra_data*)e->data)->timeout_AAAA = tAAAA; ((struct infra_data*)e->data)->timeout_AAAA = tAAAA;
((struct infra_data*)e->data)->timeout_other = tother; ((struct infra_data*)e->data)->timeout_other = tother;
@ -482,7 +486,8 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
*edns_vs = data->edns_version; *edns_vs = data->edns_version;
*edns_lame_known = data->edns_lame_known; *edns_lame_known = data->edns_lame_known;
*to = rtt_timeout(&data->rtt); *to = rtt_timeout(&data->rtt);
if(*to >= PROBE_MAXRTO && rtt_notimeout(&data->rtt)*4 <= *to) { if(*to >= PROBE_MAXRTO && (infra->infra_keep_probing ||
rtt_notimeout(&data->rtt)*4 <= *to)) {
/* delay other queries, this is the probe query */ /* delay other queries, this is the probe query */
if(!wr) { if(!wr) {
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);
@ -566,18 +571,27 @@ infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
nm, nmlen, 1); nm, nmlen, 1);
struct infra_data* data; struct infra_data* data;
int needtoinsert = 0; int needtoinsert = 0, expired = 0;
int rto = 1; int rto = 1;
time_t oldprobedelay = 0;
if(!e) { if(!e) {
if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
return 0; return 0;
needtoinsert = 1; needtoinsert = 1;
} else if(((struct infra_data*)e->data)->ttl < timenow) { } else if(((struct infra_data*)e->data)->ttl < timenow) {
oldprobedelay = ((struct infra_data*)e->data)->probedelay;
data_entry_init(infra, e, timenow); data_entry_init(infra, e, timenow);
expired = 1;
} }
/* have an entry, update the rtt */ /* have an entry, update the rtt */
data = (struct infra_data*)e->data; data = (struct infra_data*)e->data;
if(roundtrip == -1) { if(roundtrip == -1) {
if(needtoinsert || expired) {
/* timeout on entry that has expired before the timer
* keep old timeout from the function caller */
data->rtt.rto = orig_rtt;
data->probedelay = oldprobedelay;
}
rtt_lost(&data->rtt, orig_rtt); rtt_lost(&data->rtt, orig_rtt);
if(qtype == LDNS_RR_TYPE_A) { if(qtype == LDNS_RR_TYPE_A) {
if(data->timeout_A < TIMEOUT_COUNT_MAX) if(data->timeout_A < TIMEOUT_COUNT_MAX)
@ -681,7 +695,12 @@ infra_get_lame_rtt(struct infra_cache* infra,
return 0; return 0;
host = (struct infra_data*)e->data; host = (struct infra_data*)e->data;
*rtt = rtt_unclamped(&host->rtt); *rtt = rtt_unclamped(&host->rtt);
if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay if(host->rtt.rto >= PROBE_MAXRTO && timenow >= host->probedelay
&& infra->infra_keep_probing) {
/* single probe, keep probing */
if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
} else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
&& rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) { && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
/* single probe for this domain, and we are not probing */ /* single probe for this domain, and we are not probing */
/* unless the query type allows a probe to happen */ /* unless the query type allows a probe to happen */
@ -704,7 +723,8 @@ infra_get_lame_rtt(struct infra_cache* infra,
/* see if this can be a re-probe of an unresponsive server */ /* see if this can be a re-probe of an unresponsive server */
/* minus 1000 because that is outside of the RTTBAND, so /* minus 1000 because that is outside of the RTTBAND, so
* blacklisted servers stay blacklisted if this is chosen */ * blacklisted servers stay blacklisted if this is chosen */
if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT ||
infra->infra_keep_probing) {
lock_rw_unlock(&e->lock); lock_rw_unlock(&e->lock);
*rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000;
*lame = 0; *lame = 0;

View File

@ -114,6 +114,8 @@ struct infra_cache {
struct slabhash* hosts; struct slabhash* hosts;
/** TTL value for host information, in seconds */ /** TTL value for host information, in seconds */
int host_ttl; int host_ttl;
/** the hosts that are down are kept probed for recovery */
int infra_keep_probing;
/** hash table with query rates per name: rate_key, rate_data */ /** hash table with query rates per name: rate_key, rate_data */
struct slabhash* domain_rates; struct slabhash* domain_rates;
/** ratelimit settings for domains, struct domain_limit_data */ /** ratelimit settings for domains, struct domain_limit_data */

View File

@ -43,6 +43,7 @@
# include <sys/types.h> # include <sys/types.h>
#endif #endif
#include <sys/time.h> #include <sys/time.h>
#include <limits.h>
#ifdef USE_TCP_FASTOPEN #ifdef USE_TCP_FASTOPEN
#include <netinet/tcp.h> #include <netinet/tcp.h>
#endif #endif
@ -81,9 +82,6 @@
/** number of queued TCP connections for listen() */ /** number of queued TCP connections for listen() */
#define TCP_BACKLOG 256 #define TCP_BACKLOG 256
/** number of simultaneous requests a client can have */
#define TCP_MAX_REQ_SIMULTANEOUS 32
#ifndef THREADS_DISABLED #ifndef THREADS_DISABLED
/** lock on the counter of stream buffer memory */ /** lock on the counter of stream buffer memory */
static lock_basic_type stream_wait_count_lock; static lock_basic_type stream_wait_count_lock;
@ -533,7 +531,9 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
return -1; return -1;
} }
} }
# elif defined(IP_DONTFRAG) # elif defined(IP_DONTFRAG) && !defined(__APPLE__)
/* the IP_DONTFRAG option if defined in the 11.0 OSX headers,
* but does not work on that version, so we exclude it */
int off = 0; int off = 0;
if (setsockopt(s, IPPROTO_IP, IP_DONTFRAG, if (setsockopt(s, IPPROTO_IP, IP_DONTFRAG,
&off, (socklen_t)sizeof(off)) < 0) { &off, (socklen_t)sizeof(off)) < 0) {
@ -1244,8 +1244,9 @@ struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ports, listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
int harden_large_queries, uint32_t http_max_streams, int harden_large_queries, uint32_t http_max_streams,
char* http_endpoint, struct tcl_list* tcp_conn_limit, void* sslctx, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit,
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg) void* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
void *cb_arg)
{ {
struct listen_dnsport* front = (struct listen_dnsport*) struct listen_dnsport* front = (struct listen_dnsport*)
malloc(sizeof(struct listen_dnsport)); malloc(sizeof(struct listen_dnsport));
@ -1295,15 +1296,19 @@ listen_create(struct comm_base* base, struct listen_port* ports,
http_max_streams, http_endpoint, http_max_streams, http_endpoint,
tcp_conn_limit, bufsize, front->udp_buff, tcp_conn_limit, bufsize, front->udp_buff,
ports->ftype, cb, cb_arg); ports->ftype, cb, cb_arg);
cp->ssl = sslctx; if(http_notls && ports->ftype == listen_type_http)
cp->ssl = NULL;
else
cp->ssl = sslctx;
if(ports->ftype == listen_type_http) { if(ports->ftype == listen_type_http) {
if(!sslctx) { if(!sslctx && !http_notls) {
log_warn("HTTPS port configured, but no TLS " log_warn("HTTPS port configured, but no TLS "
"tls-service-key or tls-service-pem " "tls-service-key or tls-service-pem "
"set"); "set");
} }
#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB #ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
log_warn("Unbound is not compiled with an " if(!http_notls)
log_warn("Unbound is not compiled with an "
"OpenSSL version supporting ALPN " "OpenSSL version supporting ALPN "
" (OpenSSL >= 1.0.2). This is required " " (OpenSSL >= 1.0.2). This is required "
"to use DNS-over-HTTPS"); "to use DNS-over-HTTPS");
@ -1402,6 +1407,7 @@ static int
resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, int *ip_addresses_size) resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addresses, int *ip_addresses_size)
{ {
struct ifaddrs *ifa; struct ifaddrs *ifa;
void *tmpbuf;
int last_ip_addresses_size = *ip_addresses_size; int last_ip_addresses_size = *ip_addresses_size;
for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) { for(ifa = ifas; ifa != NULL; ifa = ifa->ifa_next) {
@ -1466,10 +1472,12 @@ resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addres
} }
verbose(4, "interface %s has address %s", search_ifa, addr_buf); verbose(4, "interface %s has address %s", search_ifa, addr_buf);
*ip_addresses = realloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1)); tmpbuf = realloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
if(!*ip_addresses) { if(!tmpbuf) {
log_err("realloc failed: out of memory"); log_err("realloc failed: out of memory");
return 0; return 0;
} else {
*ip_addresses = tmpbuf;
} }
(*ip_addresses)[*ip_addresses_size] = strdup(addr_buf); (*ip_addresses)[*ip_addresses_size] = strdup(addr_buf);
if(!(*ip_addresses)[*ip_addresses_size]) { if(!(*ip_addresses)[*ip_addresses_size]) {
@ -1480,10 +1488,12 @@ resolve_ifa_name(struct ifaddrs *ifas, const char *search_ifa, char ***ip_addres
} }
if (*ip_addresses_size == last_ip_addresses_size) { if (*ip_addresses_size == last_ip_addresses_size) {
*ip_addresses = realloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1)); tmpbuf = realloc(*ip_addresses, sizeof(char *) * (*ip_addresses_size + 1));
if(!*ip_addresses) { if(!tmpbuf) {
log_err("realloc failed: out of memory"); log_err("realloc failed: out of memory");
return 0; return 0;
} else {
*ip_addresses = tmpbuf;
} }
(*ip_addresses)[*ip_addresses_size] = strdup(search_ifa); (*ip_addresses)[*ip_addresses_size] = strdup(search_ifa);
if(!(*ip_addresses)[*ip_addresses_size]) { if(!(*ip_addresses)[*ip_addresses_size]) {
@ -1804,8 +1814,7 @@ tcp_req_info_setup_listen(struct tcp_req_info* req)
if(!req->cp->tcp_is_reading) if(!req->cp->tcp_is_reading)
wr = 1; wr = 1;
if(req->num_open_req + req->num_done_req < TCP_MAX_REQ_SIMULTANEOUS && if(!req->read_is_closed)
!req->read_is_closed)
rd = 1; rd = 1;
if(wr) { if(wr) {
@ -2177,9 +2186,10 @@ int http2_submit_dns_response(struct http2_session* h2_session)
int ret; int ret;
nghttp2_data_provider data_prd; nghttp2_data_provider data_prd;
char status[4]; char status[4];
nghttp2_nv headers[2]; nghttp2_nv headers[3];
struct http2_stream* h2_stream = h2_session->c->h2_stream; struct http2_stream* h2_stream = h2_session->c->h2_stream;
size_t rlen; size_t rlen;
char rlen_str[32];
if(h2_stream->rbuffer) { if(h2_stream->rbuffer) {
log_err("http2 submit response error: rbuffer already " log_err("http2 submit response error: rbuffer already "
@ -2198,6 +2208,8 @@ int http2_submit_dns_response(struct http2_session* h2_session)
} }
rlen = sldns_buffer_remaining(h2_session->c->buffer); rlen = sldns_buffer_remaining(h2_session->c->buffer);
snprintf(rlen_str, sizeof(rlen_str), "%u", (unsigned)rlen);
lock_basic_lock(&http2_response_buffer_count_lock); lock_basic_lock(&http2_response_buffer_count_lock);
if(http2_response_buffer_count + rlen > http2_response_buffer_max) { if(http2_response_buffer_count + rlen > http2_response_buffer_max) {
lock_basic_unlock(&http2_response_buffer_count_lock); lock_basic_unlock(&http2_response_buffer_count_lock);
@ -2228,13 +2240,11 @@ int http2_submit_dns_response(struct http2_session* h2_session)
headers[1].valuelen = 23; headers[1].valuelen = 23;
headers[1].flags = NGHTTP2_NV_FLAG_NONE; headers[1].flags = NGHTTP2_NV_FLAG_NONE;
/*TODO be nice and add the content-length header
headers[2].name = (uint8_t*)"content-length"; headers[2].name = (uint8_t*)"content-length";
headers[2].namelen = 14; headers[2].namelen = 14;
headers[2].value = headers[2].value = (uint8_t*)rlen_str;
headers[2].valuelen = headers[2].valuelen = strlen(rlen_str);
headers[2].flags = NGHTTP2_NV_FLAG_NONE; headers[2].flags = NGHTTP2_NV_FLAG_NONE;
*/
sldns_buffer_write(h2_stream->rbuffer, sldns_buffer_write(h2_stream->rbuffer,
sldns_buffer_current(h2_session->c->buffer), sldns_buffer_current(h2_session->c->buffer),
@ -2244,7 +2254,7 @@ int http2_submit_dns_response(struct http2_session* h2_session)
data_prd.source.ptr = h2_session; data_prd.source.ptr = h2_session;
data_prd.read_callback = http2_submit_response_read_callback; data_prd.read_callback = http2_submit_response_read_callback;
ret = nghttp2_submit_response(h2_session->session, h2_stream->stream_id, ret = nghttp2_submit_response(h2_session->session, h2_stream->stream_id,
headers, 2, &data_prd); headers, 3, &data_prd);
if(ret) { if(ret) {
verbose(VERB_QUERY, "http2: set_stream_user_data failed, " verbose(VERB_QUERY, "http2: set_stream_user_data failed, "
"error: %s", nghttp2_strerror(ret)); "error: %s", nghttp2_strerror(ret));

View File

@ -159,6 +159,7 @@ int resolve_interface_names(struct config_file* cfg, char*** resif,
* @param harden_large_queries: whether query size should be limited. * @param harden_large_queries: whether query size should be limited.
* @param http_max_streams: maximum number of HTTP/2 streams per connection. * @param http_max_streams: maximum number of HTTP/2 streams per connection.
* @param http_endpoint: HTTP endpoint to service queries on * @param http_endpoint: HTTP endpoint to service queries on
* @param http_notls: no TLS for http downstream
* @param tcp_conn_limit: TCP connection limit info. * @param tcp_conn_limit: TCP connection limit info.
* @param sslctx: nonNULL if ssl context. * @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled. * @param dtenv: nonNULL if dnstap enabled.
@ -171,8 +172,9 @@ struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ports, listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
int harden_large_queries, uint32_t http_max_streams, int harden_large_queries, uint32_t http_max_streams,
char* http_endpoint, struct tcl_list* tcp_conn_limit, void* sslctx, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit,
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg); void* sslctx, struct dt_env* dtenv, comm_point_callback_type* cb,
void *cb_arg);
/** /**
* delete the listening structure * delete the listening structure

View File

@ -157,7 +157,7 @@ local_zone_create(uint8_t* nm, size_t len, int labs,
z->namelen = len; z->namelen = len;
z->namelabs = labs; z->namelabs = labs;
lock_rw_init(&z->lock); lock_rw_init(&z->lock);
z->region = regional_create_custom(sizeof(struct regional)); z->region = regional_create_nochunk(sizeof(struct regional));
if(!z->region) { if(!z->region) {
free(z); free(z);
return NULL; return NULL;

View File

@ -1196,6 +1196,12 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
/* Copy the client's EDNS for later restore, to make sure the edns /* Copy the client's EDNS for later restore, to make sure the edns
* compare is with the correct edns options. */ * compare is with the correct edns options. */
struct edns_data edns_bak = r->edns; struct edns_data edns_bak = r->edns;
/* briefly set the replylist to null in case the
* meshsendreply calls tcpreqinfo sendreply that
* comm_point_drops because of size, and then the
* null stops the mesh state remove and thus
* reply_list modification and accounting */
struct mesh_reply* rlist = m->reply_list;
/* examine security status */ /* examine security status */
if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) || if(m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
m->s.env->cfg->ignore_cd) && rep && m->s.env->cfg->ignore_cd) && rep &&
@ -1218,15 +1224,21 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
r->h2_stream->mesh_state = NULL; r->h2_stream->mesh_state = NULL;
} }
/* send the reply */ /* send the reply */
/* We don't reuse the encoded answer if either the previous or current /* We don't reuse the encoded answer if:
* response has a local alias. We could compare the alias records * - either the previous or current response has a local alias. We could
* and still reuse the previous answer if they are the same, but that * compare the alias records and still reuse the previous answer if they
* would be complicated and error prone for the relatively minor case. * are the same, but that would be complicated and error prone for the
* So we err on the side of safety. */ * relatively minor case. So we err on the side of safety.
if(prev && prev_buffer && prev->qflags == r->qflags && * - there are registered callback functions for the given rcode, as these
* need to be called for each reply. */
if(((rcode != LDNS_RCODE_SERVFAIL &&
!m->s.env->inplace_cb_lists[inplace_cb_reply]) ||
(rcode == LDNS_RCODE_SERVFAIL &&
!m->s.env->inplace_cb_lists[inplace_cb_reply_servfail])) &&
prev && prev_buffer && prev->qflags == r->qflags &&
!prev->local_alias && !r->local_alias && !prev->local_alias && !r->local_alias &&
prev->edns.edns_present == r->edns.edns_present && prev->edns.edns_present == r->edns.edns_present &&
prev->edns.bits == r->edns.bits && prev->edns.bits == r->edns.bits &&
prev->edns.udp_size == r->edns.udp_size && prev->edns.udp_size == r->edns.udp_size &&
edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list) edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
== 0) { == 0) {
@ -1236,22 +1248,26 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t)); sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
sldns_buffer_write_at(r_buffer, 12, r->qname, sldns_buffer_write_at(r_buffer, 12, r->qname,
m->s.qinfo.qname_len); m->s.qinfo.qname_len);
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} else if(rcode) { } else if(rcode) {
m->s.qinfo.qname = r->qname; m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias; m->s.qinfo.local_alias = r->local_alias;
if(rcode == LDNS_RCODE_SERVFAIL) { if(rcode == LDNS_RCODE_SERVFAIL) {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, rcode, &r->edns, NULL, m->s.region)) rep, rcode, &r->edns, &r->query_reply, m->s.region))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} else { } else {
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
&r->edns, NULL, m->s.region)) &r->edns, &r->query_reply, m->s.region))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
} }
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid, error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
r->qflags, &r->edns); r->qflags, &r->edns);
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} else { } else {
size_t udp_size = r->edns.udp_size; size_t udp_size = r->edns.udp_size;
r->edns.edns_version = EDNS_ADVERTISED_VERSION; r->edns.edns_version = EDNS_ADVERTISED_VERSION;
@ -1261,7 +1277,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
m->s.qinfo.qname = r->qname; m->s.qinfo.qname = r->qname;
m->s.qinfo.local_alias = r->local_alias; m->s.qinfo.local_alias = r->local_alias;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, NULL, m->s.region) || LDNS_RCODE_NOERROR, &r->edns, &r->query_reply, m->s.region) ||
!apply_edns_options(&r->edns, &edns_bak, !apply_edns_options(&r->edns, &edns_bak,
m->s.env->cfg, r->query_reply.c, m->s.env->cfg, r->query_reply.c,
m->s.region) || m->s.region) ||
@ -1271,13 +1287,15 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
secure)) secure))
{ {
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s, if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region)) rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region))
r->edns.opt_list = NULL; r->edns.opt_list = NULL;
error_encode(r_buffer, LDNS_RCODE_SERVFAIL, error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
&m->s.qinfo, r->qid, r->qflags, &r->edns); &m->s.qinfo, r->qid, r->qflags, &r->edns);
} }
r->edns = edns_bak; r->edns = edns_bak;
m->reply_list = NULL;
comm_point_send_reply(&r->query_reply); comm_point_send_reply(&r->query_reply);
m->reply_list = rlist;
} }
/* account */ /* account */
log_assert(m->s.env->mesh->num_reply_addrs > 0); log_assert(m->s.env->mesh->num_reply_addrs > 0);
@ -1365,20 +1383,12 @@ void mesh_query_done(struct mesh_state* mstate)
mstate->reply_list = reply_list; mstate->reply_list = reply_list;
} else { } else {
struct sldns_buffer* r_buffer = r->query_reply.c->buffer; struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
struct mesh_reply* rlist = mstate->reply_list;
if(r->query_reply.c->tcp_req_info) { if(r->query_reply.c->tcp_req_info) {
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer; r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
prev_buffer = NULL; prev_buffer = NULL;
} }
/* briefly set the replylist to null in case the
* meshsendreply calls tcpreqinfo sendreply that
* comm_point_drops because of size, and then the
* null stops the mesh state remove and thus
* reply_list modification and accounting */
mstate->reply_list = NULL;
mesh_send_reply(mstate, mstate->s.return_rcode, rep, mesh_send_reply(mstate, mstate->s.return_rcode, rep,
r, r_buffer, prev, prev_buffer); r, r_buffer, prev, prev_buffer);
mstate->reply_list = rlist;
if(r->query_reply.c->tcp_req_info) { if(r->query_reply.c->tcp_req_info) {
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate); tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
r_buffer = NULL; r_buffer = NULL;
@ -1894,7 +1904,7 @@ mesh_serve_expired_callback(void* arg)
{ {
struct mesh_state* mstate = (struct mesh_state*) arg; struct mesh_state* mstate = (struct mesh_state*) arg;
struct module_qstate* qstate = &mstate->s; struct module_qstate* qstate = &mstate->s;
struct mesh_reply* r, *rlist; struct mesh_reply* r;
struct mesh_area* mesh = qstate->env->mesh; struct mesh_area* mesh = qstate->env->mesh;
struct dns_msg* msg; struct dns_msg* msg;
struct mesh_cb* c; struct mesh_cb* c;
@ -1999,15 +2009,8 @@ mesh_serve_expired_callback(void* arg)
r_buffer = r->query_reply.c->buffer; r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info) if(r->query_reply.c->tcp_req_info)
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer; r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
/* briefly set the replylist to null in case the meshsendreply
* calls tcpreqinfo sendreply that comm_point_drops because
* of size, and then the null stops the mesh state remove and
* thus reply_list modification and accounting */
rlist = mstate->reply_list;
mstate->reply_list = NULL;
mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep, mesh_send_reply(mstate, LDNS_RCODE_NOERROR, msg->rep,
r, r_buffer, prev, prev_buffer); r, r_buffer, prev, prev_buffer);
mstate->reply_list = rlist;
if(r->query_reply.c->tcp_req_info) if(r->query_reply.c->tcp_req_info)
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate); tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
prev = r; prev = r;

File diff suppressed because it is too large Load Diff

View File

@ -52,6 +52,7 @@ struct ub_randstate;
struct pending_tcp; struct pending_tcp;
struct waiting_tcp; struct waiting_tcp;
struct waiting_udp; struct waiting_udp;
struct reuse_tcp;
struct infra_cache; struct infra_cache;
struct port_comm; struct port_comm;
struct port_if; struct port_if;
@ -106,6 +107,9 @@ struct outside_network {
int delayclose; int delayclose;
/** timeout for delayclose */ /** timeout for delayclose */
struct timeval delay_tv; struct timeval delay_tv;
/** if we perform udp-connect, connect() for UDP socket to mitigate
* ICMP side channel leakage */
int udp_connect;
/** array of outgoing IP4 interfaces */ /** array of outgoing IP4 interfaces */
struct port_if* ip4_ifs; struct port_if* ip4_ifs;
@ -154,6 +158,21 @@ struct outside_network {
size_t num_tcp; size_t num_tcp;
/** number of tcp communication points in use. */ /** number of tcp communication points in use. */
size_t num_tcp_outgoing; size_t num_tcp_outgoing;
/**
* tree of still-open and waiting tcp connections for reuse.
* can be closed and reopened to get a new tcp connection.
* or reused to the same destination again. with timeout to close.
* Entries are of type struct reuse_tcp.
* The entries are both active and empty connections.
*/
rbtree_type tcp_reuse;
/** max number of tcp_reuse entries we want to keep open */
size_t tcp_reuse_max;
/** first and last(oldest) in lru list of reuse connections.
* the oldest can be closed to get a new free pending_tcp if needed
* The list contains empty connections, that wait for timeout or
* a new query that can use the existing connection. */
struct reuse_tcp* tcp_reuse_first, *tcp_reuse_last;
/** list of tcp comm points that are free for use */ /** list of tcp comm points that are free for use */
struct pending_tcp* tcp_free; struct pending_tcp* tcp_free;
/** list of tcp queries waiting for a buffer */ /** list of tcp queries waiting for a buffer */
@ -211,6 +230,76 @@ struct port_comm {
struct comm_point* cp; struct comm_point* cp;
}; };
/**
* Reuse TCP connection, still open can be used again.
*/
struct reuse_tcp {
/** rbtree node with links in tcp_reuse tree. key is NULL when not
* in tree. Both active and empty connections are in the tree.
* key is a pointer to this structure, the members used to compare
* are the sockaddr and and then is-ssl bool, and then ptr value is
* used in case the same address exists several times in the tree
* when there are multiple connections to the same destination to
* make the rbtree items unique. */
rbnode_type node;
/** the key for the tcp_reuse tree. address of peer, ip4 or ip6,
* and port number of peer */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** also key for tcp_reuse tree, if ssl is used */
int is_ssl;
/** lru chain, so that the oldest can be removed to get a new
* connection when all are in (re)use. oldest is last in list.
* The lru only contains empty connections waiting for reuse,
* the ones with active queries are not on the list because they
* do not need to be closed to make space for others. They already
* service a query so the close for another query does not help
* service a larger number of queries. */
struct reuse_tcp* lru_next, *lru_prev;
/** true if the reuse_tcp item is on the lru list with empty items */
int item_on_lru_list;
/** the connection to reuse, the fd is non-1 and is open.
* the addr and port determine where the connection is going,
* and is key to the rbtree. The SSL ptr determines if it is
* a TLS connection or a plain TCP connection there. And TLS
* or not is also part of the key to the rbtree.
* There is a timeout and read event on the fd, to close it. */
struct pending_tcp* pending;
/**
* The more read again value pointed to by the commpoint
* tcp_more_read_again pointer, so that it exists after commpoint
* delete
*/
int cp_more_read_again;
/**
* The more write again value pointed to by the commpoint
* tcp_more_write_again pointer, so that it exists after commpoint
* delete
*/
int cp_more_write_again;
/** rbtree with other queries waiting on the connection, by ID number,
* of type struct waiting_tcp. It is for looking up received
* answers to the structure for callback. And also to see if ID
* numbers are unused and can be used for a new query.
* The write_wait elements are also in the tree, so that ID numbers
* can be looked up also for them. They are bool write_wait_queued. */
rbtree_type tree_by_id;
/** list of queries waiting to be written on the channel,
* if NULL no queries are waiting to be written and the pending->query
* is the query currently serviced. The first is the next in line.
* They are also in the tree_by_id. Once written, the are removed
* from this list, but stay in the tree. */
struct waiting_tcp* write_wait_first, *write_wait_last;
/** the outside network it is part of */
struct outside_network* outnet;
};
/** max number of queries on a reuse connection */
#define MAX_REUSE_TCP_QUERIES 200
/** timeout for REUSE entries in milliseconds. */
#define REUSE_TIMEOUT 60000
/** /**
* A query that has an answer pending for it. * A query that has an answer pending for it.
*/ */
@ -255,12 +344,15 @@ struct pending {
struct pending_tcp { struct pending_tcp {
/** next in list of free tcp comm points, or NULL. */ /** next in list of free tcp comm points, or NULL. */
struct pending_tcp* next_free; struct pending_tcp* next_free;
/** the ID for the query; checked in reply */
uint16_t id;
/** tcp comm point it was sent on (and reply must come back on). */ /** tcp comm point it was sent on (and reply must come back on). */
struct comm_point* c; struct comm_point* c;
/** the query being serviced, NULL if the pending_tcp is unused. */ /** the query being serviced, NULL if the pending_tcp is unused. */
struct waiting_tcp* query; struct waiting_tcp* query;
/** the pre-allocated reuse tcp structure. if ->pending is nonNULL
* it is in use and the connection is waiting for reuse.
* It is here for memory pre-allocation, and used to make this
* pending_tcp wait for reuse. */
struct reuse_tcp reuse;
}; };
/** /**
@ -269,12 +361,27 @@ struct pending_tcp {
struct waiting_tcp { struct waiting_tcp {
/** /**
* next in waiting list. * next in waiting list.
* if pkt==0, this points to the pending_tcp structure. * if on_tcp_waiting_list==0, this points to the pending_tcp structure.
*/ */
struct waiting_tcp* next_waiting; struct waiting_tcp* next_waiting;
/** if true the item is on the tcp waiting list and next_waiting
* is used for that. If false, the next_waiting points to the
* pending_tcp */
int on_tcp_waiting_list;
/** next and prev in query waiting list for stream connection */
struct waiting_tcp* write_wait_prev, *write_wait_next;
/** true if the waiting_tcp structure is on the write_wait queue */
int write_wait_queued;
/** entry in reuse.tree_by_id, if key is NULL, not in tree, otherwise,
* this struct is key and sorted by ID (from waiting_tcp.id). */
rbnode_type id_node;
/** the ID for the query; checked in reply */
uint16_t id;
/** timeout event; timer keeps running whether the query is /** timeout event; timer keeps running whether the query is
* waiting for a buffer or the tcp reply is pending */ * waiting for a buffer or the tcp reply is pending */
struct comm_timer* timer; struct comm_timer* timer;
/** timeout in msec */
int timeout;
/** the outside network it is part of */ /** the outside network it is part of */
struct outside_network* outnet; struct outside_network* outnet;
/** remote address. */ /** remote address. */
@ -284,13 +391,14 @@ struct waiting_tcp {
/** /**
* The query itself, the query packet to send. * The query itself, the query packet to send.
* allocated after the waiting_tcp structure. * allocated after the waiting_tcp structure.
* set to NULL when the query is serviced and it part of pending_tcp.
* if this is NULL, the next_waiting points to the pending_tcp.
*/ */
uint8_t* pkt; uint8_t* pkt;
/** length of query packet. */ /** length of query packet. */
size_t pkt_len; size_t pkt_len;
/** callback for the timeout, error or reply to the message */ /** callback for the timeout, error or reply to the message,
* or NULL if no user is waiting. the entry uses an ID number.
* a query that was written is no longer needed, but the ID number
* and a reply will come back and can be ignored if NULL */
comm_point_callback_type* cb; comm_point_callback_type* cb;
/** callback user argument */ /** callback user argument */
void* cb_arg; void* cb_arg;
@ -298,6 +406,8 @@ struct waiting_tcp {
int ssl_upstream; int ssl_upstream;
/** ref to the tls_auth_name from the serviced_query */ /** ref to the tls_auth_name from the serviced_query */
char* tls_auth_name; char* tls_auth_name;
/** the packet was involved in an error, to stop looping errors */
int error_count;
}; };
/** /**
@ -421,6 +531,7 @@ struct serviced_query {
* msec to wait on timeouted udp sockets. * msec to wait on timeouted udp sockets.
* @param tls_use_sni: if SNI is used for TLS connections. * @param tls_use_sni: if SNI is used for TLS connections.
* @param dtenv: environment to send dnstap events with (if enabled). * @param dtenv: environment to send dnstap events with (if enabled).
* @param udp_connect: if the udp_connect option is enabled.
* @return: the new structure (with no pending answers) or NULL on error. * @return: the new structure (with no pending answers) or NULL on error.
*/ */
struct outside_network* outside_network_create(struct comm_base* base, struct outside_network* outside_network_create(struct comm_base* base,
@ -429,7 +540,8 @@ struct outside_network* outside_network_create(struct comm_base* base,
struct ub_randstate* rnd, int use_caps_for_id, int* availports, struct ub_randstate* rnd, int use_caps_for_id, int* availports,
int numavailports, size_t unwanted_threshold, int tcp_mss, int numavailports, size_t unwanted_threshold, int tcp_mss,
void (*unwanted_action)(void*), void* unwanted_param, int do_udp, void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv); void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
int udp_connect);
/** /**
* Delete outside_network structure. * Delete outside_network structure.
@ -546,6 +658,19 @@ size_t outnet_get_mem(struct outside_network* outnet);
*/ */
size_t serviced_get_mem(struct serviced_query* sq); size_t serviced_get_mem(struct serviced_query* sq);
/** Pick random ID value for a tcp stream, avoids existing IDs. */
uint16_t reuse_tcp_select_id(struct reuse_tcp* reuse,
struct outside_network* outnet);
/** find element in tree by id */
struct waiting_tcp* reuse_tcp_by_id_find(struct reuse_tcp* reuse, uint16_t id);
/** insert element in tree by id */
void reuse_tree_by_id_insert(struct reuse_tcp* reuse, struct waiting_tcp* w);
/** delete readwait waiting_tcp elements, deletes the elements in the list */
void reuse_del_readwait(rbtree_type* tree_by_id);
/** get TCP file descriptor for address, returns -1 on failure, /** get TCP file descriptor for address, returns -1 on failure,
* tcp_mss is 0 or maxseg size to set for TCP packets. */ * tcp_mss is 0 or maxseg size to set for TCP packets. */
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp); int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp);
@ -643,4 +768,10 @@ int pending_cmp(const void* key1, const void* key2);
/** compare function of serviced query rbtree */ /** compare function of serviced query rbtree */
int serviced_cmp(const void* key1, const void* key2); int serviced_cmp(const void* key1, const void* key2);
/** compare function of reuse_tcp rbtree in outside_network struct */
int reuse_cmp(const void* key1, const void* key2);
/** compare function of reuse_tcp tree_by_id rbtree */
int reuse_id_cmp(const void* key1, const void* key2);
#endif /* OUTSIDE_NETWORK_H */ #endif /* OUTSIDE_NETWORK_H */

View File

@ -440,6 +440,8 @@ rpz_create(struct config_auth* p)
respip_set_delete(r->respip_set); respip_set_delete(r->respip_set);
if(r->taglist) if(r->taglist)
free(r->taglist); free(r->taglist);
if(r->region)
regional_destroy(r->region);
free(r); free(r);
} }
return NULL; return NULL;

View File

@ -120,12 +120,19 @@ if [ ! -f "$SVR_BASE.key" ]; then
fi fi
cat >server.cnf <<EOF cat >server.cnf <<EOF
[req]
default_bits=$BITS default_bits=$BITS
default_md=$HASH default_md=$HASH
prompt=no prompt=no
distinguished_name=req_distinguished_name distinguished_name=req_distinguished_name
x509_extensions=v3_ca
[req_distinguished_name] [req_distinguished_name]
commonName=$SERVERNAME commonName=$SERVERNAME
[v3_ca]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints=critical,CA:TRUE,pathlen:0
subjectAltName=DNS:$SERVERNAME
EOF EOF
[ -f server.cnf ] || fatal "cannot create openssl configuration" [ -f server.cnf ] || fatal "cannot create openssl configuration"
@ -156,8 +163,12 @@ default_bits=$BITS
default_md=$HASH default_md=$HASH
prompt=no prompt=no
distinguished_name=req_distinguished_name distinguished_name=req_distinguished_name
req_extensions=v3_req
[req_distinguished_name] [req_distinguished_name]
commonName=$CLIENTNAME commonName=$CLIENTNAME
[v3_req]
basicConstraints=critical,CA:FALSE
subjectAltName=DNS:$CLIENTNAME
EOF EOF
[ -f client.cnf ] || fatal "cannot create openssl configuration" [ -f client.cnf ] || fatal "cannot create openssl configuration"
@ -179,6 +190,8 @@ if [ ! -f "$CTL_BASE.pem" -o $RECREATE -eq 1 ]; then
-CAkey "$SVR_BASE.key" \ -CAkey "$SVR_BASE.key" \
-CAcreateserial \ -CAcreateserial \
-$HASH \ -$HASH \
-extfile client.cnf \
-extensions v3_req \
-out "$CTL_BASE.pem" -out "$CTL_BASE.pem"
[ ! -f "CTL_BASE.pem" ] || fatal "cannot create signed client certificate" [ ! -f "CTL_BASE.pem" ] || fatal "cannot create signed client certificate"

View File

@ -170,7 +170,9 @@ config_create(void)
cfg->infra_cache_slabs = 4; cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000; cfg->infra_cache_numhosts = 10000;
cfg->infra_cache_min_rtt = 50; cfg->infra_cache_min_rtt = 50;
cfg->infra_keep_probing = 0;
cfg->delay_close = 0; cfg->delay_close = 0;
cfg->udp_connect = 1;
if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int)))) if(!(cfg->outgoing_avail_ports = (int*)calloc(65536, sizeof(int))))
goto error_exit; goto error_exit;
init_outgoing_availports(cfg->outgoing_avail_ports, 65536); init_outgoing_availports(cfg->outgoing_avail_ports, 65536);
@ -321,8 +323,8 @@ config_create(void)
cfg->qname_minimisation_strict = 0; cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0; cfg->shm_enable = 0;
cfg->shm_key = 11777; cfg->shm_key = 11777;
cfg->edns_client_tags = NULL; cfg->edns_client_strings = NULL;
cfg->edns_client_tag_opcode = LDNS_EDNS_CLIENT_TAG; cfg->edns_client_string_opcode = 65001;
cfg->dnscrypt = 0; cfg->dnscrypt = 0;
cfg->dnscrypt_port = 0; cfg->dnscrypt_port = 0;
cfg->dnscrypt_provider = NULL; cfg->dnscrypt_provider = NULL;
@ -522,11 +524,12 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STR("tls-ciphersuites:", tls_ciphersuites) else S_STR("tls-ciphersuites:", tls_ciphersuites)
else S_YNO("tls-use-sni:", tls_use_sni) else S_YNO("tls-use-sni:", tls_use_sni)
else S_NUMBER_NONZERO("https-port:", https_port) else S_NUMBER_NONZERO("https-port:", https_port)
else S_STR("http-endpoint", http_endpoint) else S_STR("http-endpoint:", http_endpoint)
else S_NUMBER_NONZERO("http-max-streams", http_max_streams) else S_NUMBER_NONZERO("http-max-streams:", http_max_streams)
else S_MEMSIZE("http-query-buffer-size", http_query_buffer_size) else S_MEMSIZE("http-query-buffer-size:", http_query_buffer_size)
else S_MEMSIZE("http-response-buffer-size", http_response_buffer_size) else S_MEMSIZE("http-response-buffer-size:", http_response_buffer_size)
else S_YNO("http-nodelay", http_nodelay) else S_YNO("http-nodelay:", http_nodelay)
else S_YNO("http-notls-downstream:", http_notls_downstream)
else S_YNO("interface-automatic:", if_automatic) else S_YNO("interface-automatic:", if_automatic)
else S_YNO("use-systemd:", use_systemd) else S_YNO("use-systemd:", use_systemd)
else S_YNO("do-daemonize:", do_daemonize) else S_YNO("do-daemonize:", do_daemonize)
@ -562,10 +565,12 @@ int config_set_option(struct config_file* cfg, const char* opt,
IS_NUMBER_OR_ZERO; cfg->infra_cache_min_rtt = atoi(val); IS_NUMBER_OR_ZERO; cfg->infra_cache_min_rtt = atoi(val);
RTT_MIN_TIMEOUT=cfg->infra_cache_min_rtt; RTT_MIN_TIMEOUT=cfg->infra_cache_min_rtt;
} }
else S_YNO("infra-keep-probing:", infra_keep_probing)
else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl) else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl)
else S_POW2("infra-cache-slabs:", infra_cache_slabs) else S_POW2("infra-cache-slabs:", infra_cache_slabs)
else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts) else S_SIZET_NONZERO("infra-cache-numhosts:", infra_cache_numhosts)
else S_NUMBER_OR_ZERO("delay-close:", delay_close) else S_NUMBER_OR_ZERO("delay-close:", delay_close)
else S_YNO("udp-connect:", udp_connect)
else S_STR("chroot:", chrootdir) else S_STR("chroot:", chrootdir)
else S_STR("username:", username) else S_STR("username:", username)
else S_STR("directory:", directory) else S_STR("directory:", directory)
@ -958,8 +963,10 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_DEC(opt, "infra-host-ttl", host_ttl) else O_DEC(opt, "infra-host-ttl", host_ttl)
else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs) else O_DEC(opt, "infra-cache-slabs", infra_cache_slabs)
else O_DEC(opt, "infra-cache-min-rtt", infra_cache_min_rtt) else O_DEC(opt, "infra-cache-min-rtt", infra_cache_min_rtt)
else O_YNO(opt, "infra-keep-probing", infra_keep_probing)
else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts) else O_MEM(opt, "infra-cache-numhosts", infra_cache_numhosts)
else O_UNS(opt, "delay-close", delay_close) else O_UNS(opt, "delay-close", delay_close)
else O_YNO(opt, "udp-connect", udp_connect)
else O_YNO(opt, "do-ip4", do_ip4) else O_YNO(opt, "do-ip4", do_ip4)
else O_YNO(opt, "do-ip6", do_ip6) else O_YNO(opt, "do-ip6", do_ip6)
else O_YNO(opt, "do-udp", do_udp) else O_YNO(opt, "do-udp", do_udp)
@ -990,6 +997,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_MEM(opt, "http-query-buffer-size", http_query_buffer_size) else O_MEM(opt, "http-query-buffer-size", http_query_buffer_size)
else O_MEM(opt, "http-response-buffer-size", http_response_buffer_size) else O_MEM(opt, "http-response-buffer-size", http_response_buffer_size)
else O_YNO(opt, "http-nodelay", http_nodelay) else O_YNO(opt, "http-nodelay", http_nodelay)
else O_YNO(opt, "http-notls-downstream", http_notls_downstream)
else O_YNO(opt, "use-systemd", use_systemd) else O_YNO(opt, "use-systemd", use_systemd)
else O_YNO(opt, "do-daemonize", do_daemonize) else O_YNO(opt, "do-daemonize", do_daemonize)
else O_STR(opt, "chroot", chrootdir) else O_STR(opt, "chroot", chrootdir)
@ -1150,7 +1158,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS3(opt, "access-control-tag-action", acl_tag_actions) else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
else O_LS3(opt, "access-control-tag-data", acl_tag_datas) else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
else O_LS2(opt, "access-control-view", acl_view) else O_LS2(opt, "access-control-view", acl_view)
else O_LS2(opt, "edns-client-tags", edns_client_tags) else O_LS2(opt, "edns-client-strings", edns_client_strings)
#ifdef USE_IPSECMOD #ifdef USE_IPSECMOD
else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled) else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled)
else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus) else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus)
@ -1519,7 +1527,7 @@ config_delete(struct config_file* cfg)
config_deldblstrlist(cfg->ratelimit_below_domain); config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script); config_delstrlist(cfg->python_script);
config_delstrlist(cfg->dynlib_file); config_delstrlist(cfg->dynlib_file);
config_deldblstrlist(cfg->edns_client_tags); config_deldblstrlist(cfg->edns_client_strings);
#ifdef USE_IPSECMOD #ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook); free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist); config_delstrlist(cfg->ipsecmod_whitelist);

View File

@ -143,6 +143,8 @@ struct config_file {
size_t http_response_buffer_size; size_t http_response_buffer_size;
/** set TCP_NODELAY option for http sockets */ /** set TCP_NODELAY option for http sockets */
int http_nodelay; int http_nodelay;
/** Disable TLS for http sockets downstream */
int http_notls_downstream;
/** outgoing port range number of ports (per thread) */ /** outgoing port range number of ports (per thread) */
int outgoing_num_ports; int outgoing_num_ports;
@ -179,8 +181,12 @@ struct config_file {
size_t infra_cache_numhosts; size_t infra_cache_numhosts;
/** min value for infra cache rtt */ /** min value for infra cache rtt */
int infra_cache_min_rtt; int infra_cache_min_rtt;
/** keep probing hosts that are down */
int infra_keep_probing;
/** delay close of udp-timeouted ports, if 0 no delayclose. in msec */ /** delay close of udp-timeouted ports, if 0 no delayclose. in msec */
int delay_close; int delay_close;
/** udp_connect enable uses UDP connect to mitigate ICMP side channel */
int udp_connect;
/** the target fetch policy for the iterator */ /** the target fetch policy for the iterator */
char* target_fetch_policy; char* target_fetch_policy;
@ -562,10 +568,10 @@ struct config_file {
/** SHM data - key for the shm */ /** SHM data - key for the shm */
int shm_key; int shm_key;
/** list of EDNS client tag entries, linked list */ /** list of EDNS client string entries, linked list */
struct config_str2list* edns_client_tags; struct config_str2list* edns_client_strings;
/** EDNS opcode to use for EDNS client tags */ /** EDNS opcode to use for EDNS client strings */
uint16_t edns_client_tag_opcode; uint16_t edns_client_string_opcode;
/** DNSCrypt */ /** DNSCrypt */
/** true to enable dnscrypt */ /** true to enable dnscrypt */

View File

@ -263,6 +263,7 @@ http-max-streams{COLON} { YDVAR(1, VAR_HTTP_MAX_STREAMS) }
http-query-buffer-size{COLON} { YDVAR(1, VAR_HTTP_QUERY_BUFFER_SIZE) } http-query-buffer-size{COLON} { YDVAR(1, VAR_HTTP_QUERY_BUFFER_SIZE) }
http-response-buffer-size{COLON} { YDVAR(1, VAR_HTTP_RESPONSE_BUFFER_SIZE) } http-response-buffer-size{COLON} { YDVAR(1, VAR_HTTP_RESPONSE_BUFFER_SIZE) }
http-nodelay{COLON} { YDVAR(1, VAR_HTTP_NODELAY) } http-nodelay{COLON} { YDVAR(1, VAR_HTTP_NODELAY) }
http-notls-downstream{COLON} { YDVAR(1, VAR_HTTP_NOTLS_DOWNSTREAM) }
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) } use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) } do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) } interface{COLON} { YDVAR(1, VAR_INTERFACE) }
@ -297,9 +298,11 @@ infra-cache-slabs{COLON} { YDVAR(1, VAR_INFRA_CACHE_SLABS) }
infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) } infra-cache-numhosts{COLON} { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) }
infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) } infra-cache-lame-size{COLON} { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) }
infra-cache-min-rtt{COLON} { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) } infra-cache-min-rtt{COLON} { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) }
infra-keep-probing{COLON} { YDVAR(1, VAR_INFRA_KEEP_PROBING) }
num-queries-per-thread{COLON} { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) } num-queries-per-thread{COLON} { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) }
jostle-timeout{COLON} { YDVAR(1, VAR_JOSTLE_TIMEOUT) } jostle-timeout{COLON} { YDVAR(1, VAR_JOSTLE_TIMEOUT) }
delay-close{COLON} { YDVAR(1, VAR_DELAY_CLOSE) } delay-close{COLON} { YDVAR(1, VAR_DELAY_CLOSE) }
udp-connect{COLON} { YDVAR(1, VAR_UDP_CONNECT) }
target-fetch-policy{COLON} { YDVAR(1, VAR_TARGET_FETCH_POLICY) } target-fetch-policy{COLON} { YDVAR(1, VAR_TARGET_FETCH_POLICY) }
harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) } harden-short-bufsize{COLON} { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) }
harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) } harden-large-queries{COLON} { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) }
@ -527,8 +530,8 @@ name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) } name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
edns-client-tag{COLON} { YDVAR(2, VAR_EDNS_CLIENT_TAG) } edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
edns-client-tag-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_TAG_OPCODE) } edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } <INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
/* Quoted strings. Strip leading and ending quotes */ /* Quoted strings. Strip leading and ending quotes */

View File

@ -114,11 +114,11 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE %token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
%token VAR_HTTPS_PORT VAR_HTTP_ENDPOINT VAR_HTTP_MAX_STREAMS %token VAR_HTTPS_PORT VAR_HTTP_ENDPOINT VAR_HTTP_MAX_STREAMS
%token VAR_HTTP_QUERY_BUFFER_SIZE VAR_HTTP_RESPONSE_BUFFER_SIZE %token VAR_HTTP_QUERY_BUFFER_SIZE VAR_HTTP_RESPONSE_BUFFER_SIZE
%token VAR_HTTP_NODELAY %token VAR_HTTP_NODELAY VAR_HTTP_NOTLS_DOWNSTREAM
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE %token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UDP_CONNECT
%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES %token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
%token VAR_INFRA_CACHE_MIN_RTT %token VAR_INFRA_CACHE_MIN_RTT VAR_INFRA_KEEP_PROBING
%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA
%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP %token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP
%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE %token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE
@ -178,7 +178,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE %token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME %token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_TAG VAR_EDNS_CLIENT_TAG_OPCODE %token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
%token VAR_EDNS_CLIENT_STRING_OPCODE
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -249,14 +250,14 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ssl_service_key | server_ssl_service_pem | server_ssl_port | server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
server_https_port | server_http_endpoint | server_http_max_streams | server_https_port | server_http_endpoint | server_http_max_streams |
server_http_query_buffer_size | server_http_response_buffer_size | server_http_query_buffer_size | server_http_response_buffer_size |
server_http_nodelay | server_http_nodelay | server_http_notls_downstream |
server_minimal_responses | server_rrset_roundrobin | server_max_udp_size | server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
server_so_reuseport | server_delay_close | server_so_reuseport | server_delay_close | server_udp_connect |
server_unblock_lan_zones | server_insecure_lan_zones | server_unblock_lan_zones | server_insecure_lan_zones |
server_dns64_prefix | server_dns64_synthall | server_dns64_ignore_aaaa | server_dns64_prefix | server_dns64_synthall | server_dns64_ignore_aaaa |
server_infra_cache_min_rtt | server_harden_algo_downgrade | server_infra_cache_min_rtt | server_harden_algo_downgrade |
server_ip_transparent | server_ip_ratelimit | server_ratelimit | server_ip_transparent | server_ip_ratelimit | server_ratelimit |
server_ip_dscp | server_ip_dscp | server_infra_keep_probing |
server_ip_ratelimit_slabs | server_ratelimit_slabs | server_ip_ratelimit_slabs | server_ratelimit_slabs |
server_ip_ratelimit_size | server_ratelimit_size | server_ip_ratelimit_size | server_ratelimit_size |
server_ratelimit_for_domain | server_ratelimit_for_domain |
@ -291,8 +292,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_unknown_server_time_limit | server_log_tag_queryreply | server_unknown_server_time_limit | server_log_tag_queryreply |
server_stream_wait_size | server_tls_ciphers | server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys | server_tls_ciphersuites | server_tls_session_ticket_keys |
server_tls_use_sni | server_edns_client_tag | server_tls_use_sni | server_edns_client_string |
server_edns_client_tag_opcode server_edns_client_string_opcode
; ;
stubstart: VAR_STUB_ZONE stubstart: VAR_STUB_ZONE
{ {
@ -982,6 +983,7 @@ server_https_port: VAR_HTTPS_PORT STRING_ARG
if(atoi($2) == 0) if(atoi($2) == 0)
yyerror("port number expected"); yyerror("port number expected");
else cfg_parser->cfg->https_port = atoi($2); else cfg_parser->cfg->https_port = atoi($2);
free($2);
}; };
server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG
{ {
@ -1030,6 +1032,14 @@ server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG
yyerror("expected yes or no."); yyerror("expected yes or no.");
else cfg_parser->cfg->http_nodelay = (strcmp($2, "yes")==0); else cfg_parser->cfg->http_nodelay = (strcmp($2, "yes")==0);
free($2); free($2);
}
server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG
{
OUTYY(("P(server_http_notls_downstream:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->http_notls_downstream = (strcmp($2, "yes")==0);
free($2);
}; };
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
{ {
@ -1434,6 +1444,15 @@ server_delay_close: VAR_DELAY_CLOSE STRING_ARG
free($2); free($2);
} }
; ;
server_udp_connect: VAR_UDP_CONNECT STRING_ARG
{
OUTYY(("P(server_udp_connect:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->udp_connect = (strcmp($2, "yes")==0);
free($2);
}
;
server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG
{ {
OUTYY(("P(server_unblock_lan_zones:%s)\n", $2)); OUTYY(("P(server_unblock_lan_zones:%s)\n", $2));
@ -1531,6 +1550,16 @@ server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG
free($2); free($2);
} }
; ;
server_infra_keep_probing: VAR_INFRA_KEEP_PROBING STRING_ARG
{
OUTYY(("P(server_infra_keep_probing:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->infra_keep_probing =
(strcmp($2, "yes")==0);
free($2);
}
;
server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG
{ {
OUTYY(("P(server_target_fetch_policy:%s)\n", $2)); OUTYY(("P(server_target_fetch_policy:%s)\n", $2));
@ -2465,29 +2494,24 @@ server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
#endif #endif
} }
; ;
server_edns_client_tag: VAR_EDNS_CLIENT_TAG STRING_ARG STRING_ARG server_edns_client_string: VAR_EDNS_CLIENT_STRING STRING_ARG STRING_ARG
{ {
int tag_data; OUTYY(("P(server_edns_client_string:%s %s)\n", $2, $3));
OUTYY(("P(server_edns_client_tag:%s %s)\n", $2, $3));
tag_data = atoi($3);
if(tag_data > 65535 || tag_data < 0 ||
(tag_data == 0 && (strlen($3) != 1 || $3[0] != '0')))
yyerror("edns-client-tag data invalid, needs to be a "
"number from 0 to 65535");
if(!cfg_str2list_insert( if(!cfg_str2list_insert(
&cfg_parser->cfg->edns_client_tags, $2, $3)) &cfg_parser->cfg->edns_client_strings, $2, $3))
fatal_exit("out of memory adding " fatal_exit("out of memory adding "
"edns-client-tag"); "edns-client-string");
} }
; ;
server_edns_client_tag_opcode: VAR_EDNS_CLIENT_TAG_OPCODE STRING_ARG server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG
{ {
OUTYY(("P(edns_client_tag_opcode:%s)\n", $2)); OUTYY(("P(edns_client_string_opcode:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0) if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("option code expected"); yyerror("option code expected");
else if(atoi($2) > 65535 || atoi($2) < 0) else if(atoi($2) > 65535 || atoi($2) < 0)
yyerror("option code must be in interval [0, 65535]"); yyerror("option code must be in interval [0, 65535]");
else cfg_parser->cfg->edns_client_tag_opcode = atoi($2); else cfg_parser->cfg->edns_client_string_opcode = atoi($2);
free($2);
} }
; ;

View File

@ -624,6 +624,9 @@ positive_answer(struct reply_info* rep, uint16_t qtype) {
for(i=0;i<rep->an_numrrsets; i++) { for(i=0;i<rep->an_numrrsets; i++) {
if(ntohs(rep->rrsets[i]->rk.type) == qtype) { if(ntohs(rep->rrsets[i]->rk.type) == qtype) {
/* for priming queries, type NS, include addresses */
if(qtype == LDNS_RR_TYPE_NS)
return 0;
/* in case it is a wildcard with DNSSEC, there will /* in case it is a wildcard with DNSSEC, there will
* be NSEC/NSEC3 records in the authority section * be NSEC/NSEC3 records in the authority section
* that we cannot remove */ * that we cannot remove */

View File

@ -552,7 +552,7 @@ struct edns_option* edns_opt_list_find(struct edns_option* list, uint16_t code);
* @param rep: Reply info. Could be NULL. * @param rep: Reply info. Could be NULL.
* @param rcode: return code. * @param rcode: return code.
* @param edns: edns data of the reply. * @param edns: edns data of the reply.
* @param repinfo: comm_reply. NULL. * @param repinfo: comm_reply. Reply information for a communication point.
* @param region: region to store data. * @param region: region to store data.
* @return false on failure (a callback function returned an error). * @return false on failure (a callback function returned an error).
*/ */

View File

@ -53,81 +53,84 @@
#include "edns.h" #include "edns.h"
#endif #endif
struct edns_tags* edns_tags_create(void) struct edns_strings* edns_strings_create(void)
{ {
struct edns_tags* edns_tags = calloc(1, sizeof(struct edns_tags)); struct edns_strings* edns_strings = calloc(1,
if(!edns_tags) sizeof(struct edns_strings));
if(!edns_strings)
return NULL; return NULL;
if(!(edns_tags->region = regional_create())) { if(!(edns_strings->region = regional_create())) {
edns_tags_delete(edns_tags); edns_strings_delete(edns_strings);
return NULL; return NULL;
} }
return edns_tags; return edns_strings;
} }
void edns_tags_delete(struct edns_tags* edns_tags) void edns_strings_delete(struct edns_strings* edns_strings)
{ {
if(!edns_tags) if(!edns_strings)
return; return;
regional_destroy(edns_tags->region); regional_destroy(edns_strings->region);
free(edns_tags); free(edns_strings);
} }
static int static int
edns_tags_client_insert(struct edns_tags* edns_tags, edns_strings_client_insert(struct edns_strings* edns_strings,
struct sockaddr_storage* addr, socklen_t addrlen, int net, struct sockaddr_storage* addr, socklen_t addrlen, int net,
uint16_t tag_data) const char* string)
{ {
struct edns_tag_addr* eta = regional_alloc_zero(edns_tags->region, struct edns_string_addr* esa = regional_alloc_zero(edns_strings->region,
sizeof(struct edns_tag_addr)); sizeof(struct edns_string_addr));
if(!eta) if(!esa)
return 0; return 0;
eta->tag_data = tag_data; esa->string_len = strlen(string);
if(!addr_tree_insert(&edns_tags->client_tags, &eta->node, addr, addrlen, esa->string = regional_alloc_init(edns_strings->region, string,
net)) { esa->string_len);
verbose(VERB_QUERY, "duplicate EDNS client tag ignored."); if(!esa->string)
return 0;
if(!addr_tree_insert(&edns_strings->client_strings, &esa->node, addr,
addrlen, net)) {
verbose(VERB_QUERY, "duplicate EDNS client string ignored.");
} }
return 1; return 1;
} }
int edns_tags_apply_cfg(struct edns_tags* edns_tags, int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config) struct config_file* config)
{ {
struct config_str2list* c; struct config_str2list* c;
regional_free_all(edns_tags->region); regional_free_all(edns_strings->region);
addr_tree_init(&edns_tags->client_tags); addr_tree_init(&edns_strings->client_strings);
for(c=config->edns_client_tags; c; c=c->next) { for(c=config->edns_client_strings; c; c=c->next) {
struct sockaddr_storage addr; struct sockaddr_storage addr;
socklen_t addrlen; socklen_t addrlen;
int net; int net;
uint16_t tag_data;
log_assert(c->str && c->str2); log_assert(c->str && c->str2);
if(!netblockstrtoaddr(c->str, UNBOUND_DNS_PORT, &addr, &addrlen, if(!netblockstrtoaddr(c->str, UNBOUND_DNS_PORT, &addr, &addrlen,
&net)) { &net)) {
log_err("cannot parse EDNS client tag IP netblock: %s", log_err("cannot parse EDNS client string IP netblock: "
c->str); "%s", c->str);
return 0; return 0;
} }
tag_data = atoi(c->str2); /* validated in config parser */ if(!edns_strings_client_insert(edns_strings, &addr, addrlen,
if(!edns_tags_client_insert(edns_tags, &addr, addrlen, net, net, c->str2)) {
tag_data)) { log_err("out of memory while adding EDNS strings");
log_err("out of memory while adding EDNS tags");
return 0; return 0;
} }
} }
edns_tags->client_tag_opcode = config->edns_client_tag_opcode; edns_strings->client_string_opcode = config->edns_client_string_opcode;
addr_tree_init_parents(&edns_tags->client_tags); addr_tree_init_parents(&edns_strings->client_strings);
return 1; return 1;
} }
struct edns_tag_addr* struct edns_string_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr, edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen) socklen_t addrlen)
{ {
return (struct edns_tag_addr*)addr_tree_lookup(tree, addr, addrlen); return (struct edns_string_addr*)addr_tree_lookup(tree, addr, addrlen);
} }
static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in, static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in,

View File

@ -50,58 +50,60 @@ struct comm_point;
struct regional; struct regional;
/** /**
* Structure containing all EDNS tags. * Structure containing all EDNS strings.
*/ */
struct edns_tags { struct edns_strings {
/** Tree of EDNS client tags to use in upstream queries, per address /** Tree of EDNS client strings to use in upstream queries, per address
* prefix. Contains nodes of type edns_tag_addr. */ * prefix. Contains nodes of type edns_string_addr. */
rbtree_type client_tags; rbtree_type client_strings;
/** EDNS opcode to use for client tags */ /** EDNS opcode to use for client strings */
uint16_t client_tag_opcode; uint16_t client_string_opcode;
/** region to allocate tree nodes in */ /** region to allocate tree nodes in */
struct regional* region; struct regional* region;
}; };
/** /**
* EDNS tag. Node of rbtree, containing tag and prefix. * EDNS string. Node of rbtree, containing string and prefix.
*/ */
struct edns_tag_addr { struct edns_string_addr {
/** node in address tree, used for tree lookups. Need to be the first /** node in address tree, used for tree lookups. Need to be the first
* member of this struct. */ * member of this struct. */
struct addr_tree_node node; struct addr_tree_node node;
/** tag data, in host byte ordering */ /** string, ascii format */
uint16_t tag_data; uint8_t* string;
/** length of string */
size_t string_len;
}; };
/** /**
* Create structure to hold EDNS tags * Create structure to hold EDNS strings
* @return: newly created edns_tags, NULL on alloc failure. * @return: newly created edns_strings, NULL on alloc failure.
*/ */
struct edns_tags* edns_tags_create(void); struct edns_strings* edns_strings_create(void);
/** Delete EDNS tags structure /** Delete EDNS strings structure
* @param edns_tags: struct to delete * @param edns_strings: struct to delete
*/ */
void edns_tags_delete(struct edns_tags* edns_tags); void edns_strings_delete(struct edns_strings* edns_strings);
/** /**
* Add configured EDNS tags * Add configured EDNS strings
* @param edns_tags: edns tags to apply config to * @param edns_strings: edns strings to apply config to
* @param config: struct containing EDNS tags configuration * @param config: struct containing EDNS strings configuration
* @return 0 on error * @return 0 on error
*/ */
int edns_tags_apply_cfg(struct edns_tags* edns_tags, int edns_strings_apply_cfg(struct edns_strings* edns_strings,
struct config_file* config); struct config_file* config);
/** /**
* Find tag for address. * Find string for address.
* @param tree: tree containing EDNS tags per address prefix. * @param tree: tree containing EDNS strings per address prefix.
* @param addr: address to use for tree lookup * @param addr: address to use for tree lookup
* @param addrlen: length of address * @param addrlen: length of address
* @return: matching tree node, NULL otherwise * @return: matching tree node, NULL otherwise
*/ */
struct edns_tag_addr* struct edns_string_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr, edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen); socklen_t addrlen);
/** /**

View File

@ -229,6 +229,8 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
else if(fptr == &fwd_cmp) return 1; else if(fptr == &fwd_cmp) return 1;
else if(fptr == &pending_cmp) return 1; else if(fptr == &pending_cmp) return 1;
else if(fptr == &serviced_cmp) return 1; else if(fptr == &serviced_cmp) return 1;
else if(fptr == &reuse_cmp) return 1;
else if(fptr == &reuse_id_cmp) return 1;
else if(fptr == &name_tree_compare) return 1; else if(fptr == &name_tree_compare) return 1;
else if(fptr == &order_lock_cmp) return 1; else if(fptr == &order_lock_cmp) return 1;
else if(fptr == &codeline_cmp) return 1; else if(fptr == &codeline_cmp) return 1;

View File

@ -5290,6 +5290,7 @@
22005, 22005,
22273, 22273,
22305, 22305,
22333,
22335, 22335,
22343, 22343,
22347, 22347,

View File

@ -520,8 +520,8 @@ struct module_env {
struct edns_known_option* edns_known_options; struct edns_known_option* edns_known_options;
/* Number of known edns options */ /* Number of known edns options */
size_t edns_known_options_num; size_t edns_known_options_num;
/** EDNS client tag information */ /** EDNS client string information */
struct edns_tags* edns_tags; struct edns_strings* edns_strings;
/* Make every mesh state unique, do not aggregate mesh states. */ /* Make every mesh state unique, do not aggregate mesh states. */
int unique_mesh; int unique_mesh;

View File

@ -341,10 +341,15 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
if(sldns_buffer_remaining(packet) == 0) if(sldns_buffer_remaining(packet) == 0)
log_err("error: send empty UDP packet"); log_err("error: send empty UDP packet");
#endif #endif
log_assert(addr && addrlen > 0); if(addr) {
sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), log_assert(addr && addrlen > 0);
sldns_buffer_remaining(packet), 0, sent = sendto(c->fd, (void*)sldns_buffer_begin(packet),
addr, addrlen); sldns_buffer_remaining(packet), 0,
addr, addrlen);
} else {
sent = send(c->fd, (void*)sldns_buffer_begin(packet),
sldns_buffer_remaining(packet), 0);
}
if(sent == -1) { if(sent == -1) {
/* try again and block, waiting for IO to complete, /* try again and block, waiting for IO to complete,
* we want to send the answer, and we will wait for * we want to send the answer, and we will wait for
@ -574,6 +579,32 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet,
#endif /* AF_INET6 && IPV6_PKTINFO && HAVE_SENDMSG */ #endif /* AF_INET6 && IPV6_PKTINFO && HAVE_SENDMSG */
} }
/** return true is UDP receive error needs to be logged */
static int udp_recv_needs_log(int err)
{
switch(err) {
case ECONNREFUSED:
# ifdef ENETUNREACH
case ENETUNREACH:
# endif
# ifdef EHOSTDOWN
case EHOSTDOWN:
# endif
# ifdef EHOSTUNREACH
case EHOSTUNREACH:
# endif
# ifdef ENETDOWN
case ENETDOWN:
# endif
if(verbosity >= VERB_ALGO)
return 1;
return 0;
default:
break;
}
return 1;
}
void void
comm_point_udp_ancil_callback(int fd, short event, void* arg) comm_point_udp_ancil_callback(int fd, short event, void* arg)
{ {
@ -616,7 +647,8 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
msg.msg_flags = 0; msg.msg_flags = 0;
rcv = recvmsg(fd, &msg, 0); rcv = recvmsg(fd, &msg, 0);
if(rcv == -1) { if(rcv == -1) {
if(errno != EAGAIN && errno != EINTR) { if(errno != EAGAIN && errno != EINTR
&& udp_recv_needs_log(errno)) {
log_err("recvmsg failed: %s", strerror(errno)); log_err("recvmsg failed: %s", strerror(errno));
} }
return; return;
@ -697,7 +729,8 @@ comm_point_udp_callback(int fd, short event, void* arg)
(struct sockaddr*)&rep.addr, &rep.addrlen); (struct sockaddr*)&rep.addr, &rep.addrlen);
if(rcv == -1) { if(rcv == -1) {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno != EAGAIN && errno != EINTR) if(errno != EAGAIN && errno != EINTR
&& udp_recv_needs_log(errno))
log_err("recvfrom %d failed: %s", log_err("recvfrom %d failed: %s",
fd, strerror(errno)); fd, strerror(errno));
#else #else
@ -965,6 +998,10 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* clear leftover flags from previous use, and then set the /* clear leftover flags from previous use, and then set the
* correct event base for the event structure for libevent */ * correct event base for the event structure for libevent */
ub_event_free(c_hdl->ev->ev); ub_event_free(c_hdl->ev->ev);
if((c_hdl->type == comm_tcp && c_hdl->tcp_req_info) ||
c_hdl->type == comm_local || c_hdl->type == comm_raw)
c_hdl->tcp_do_toggle_rw = 0;
else c_hdl->tcp_do_toggle_rw = 1;
if(c_hdl->type == comm_http) { if(c_hdl->type == comm_http) {
#ifdef HAVE_NGHTTP2 #ifdef HAVE_NGHTTP2
@ -978,6 +1015,10 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
log_warn("failed to submit http2 settings"); log_warn("failed to submit http2 settings");
return; return;
} }
if(!c->ssl) {
c_hdl->tcp_do_toggle_rw = 0;
c_hdl->use_h2 = 1;
}
#endif #endif
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1, c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1,
UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT, UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT,
@ -1042,6 +1083,8 @@ reclaim_tcp_handler(struct comm_point* c)
comm_point_start_listening(c->tcp_parent, -1, -1); comm_point_start_listening(c->tcp_parent, -1, -1);
} }
} }
c->tcp_more_read_again = NULL;
c->tcp_more_write_again = NULL;
} }
/** do the callback when writing is done */ /** do the callback when writing is done */
@ -1049,16 +1092,27 @@ static void
tcp_callback_writer(struct comm_point* c) tcp_callback_writer(struct comm_point* c)
{ {
log_assert(c->type == comm_tcp); log_assert(c->type == comm_tcp);
sldns_buffer_clear(c->buffer); if(!c->tcp_write_and_read) {
sldns_buffer_clear(c->buffer);
c->tcp_byte_count = 0;
}
if(c->tcp_do_toggle_rw) if(c->tcp_do_toggle_rw)
c->tcp_is_reading = 1; c->tcp_is_reading = 1;
c->tcp_byte_count = 0;
/* switch from listening(write) to listening(read) */ /* switch from listening(write) to listening(read) */
if(c->tcp_req_info) { if(c->tcp_req_info) {
tcp_req_info_handle_writedone(c->tcp_req_info); tcp_req_info_handle_writedone(c->tcp_req_info);
} else { } else {
comm_point_stop_listening(c); comm_point_stop_listening(c);
comm_point_start_listening(c, -1, c->tcp_timeout_msec); if(c->tcp_write_and_read) {
fptr_ok(fptr_whitelist_comm_point(c->callback));
if( (*c->callback)(c, c->cb_arg, NETEVENT_PKT_WRITTEN,
&c->repinfo) ) {
comm_point_start_listening(c, -1,
c->tcp_timeout_msec);
}
} else {
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
}
} }
} }
@ -1361,10 +1415,28 @@ ssl_handle_write(struct comm_point* c)
} }
/* ignore return, if fails we may simply block */ /* ignore return, if fails we may simply block */
(void)SSL_set_mode(c->ssl, (long)SSL_MODE_ENABLE_PARTIAL_WRITE); (void)SSL_set_mode(c->ssl, (long)SSL_MODE_ENABLE_PARTIAL_WRITE);
if(c->tcp_byte_count < sizeof(uint16_t)) { if((c->tcp_write_and_read?c->tcp_write_byte_count:c->tcp_byte_count) < sizeof(uint16_t)) {
uint16_t len = htons(sldns_buffer_limit(c->buffer)); uint16_t len = htons(c->tcp_write_and_read?c->tcp_write_pkt_len:sldns_buffer_limit(c->buffer));
ERR_clear_error(); ERR_clear_error();
if(sizeof(uint16_t)+sldns_buffer_remaining(c->buffer) < if(c->tcp_write_and_read) {
if(c->tcp_write_pkt_len + 2 < LDNS_RR_BUF_SIZE) {
/* combine the tcp length and the query for
* write, this emulates writev */
uint8_t buf[LDNS_RR_BUF_SIZE];
memmove(buf, &len, sizeof(uint16_t));
memmove(buf+sizeof(uint16_t),
c->tcp_write_pkt,
c->tcp_write_pkt_len);
r = SSL_write(c->ssl,
(void*)(buf+c->tcp_write_byte_count),
c->tcp_write_pkt_len + 2 -
c->tcp_write_byte_count);
} else {
r = SSL_write(c->ssl,
(void*)(((uint8_t*)&len)+c->tcp_write_byte_count),
(int)(sizeof(uint16_t)-c->tcp_write_byte_count));
}
} else if(sizeof(uint16_t)+sldns_buffer_remaining(c->buffer) <
LDNS_RR_BUF_SIZE) { LDNS_RR_BUF_SIZE) {
/* combine the tcp length and the query for write, /* combine the tcp length and the query for write,
* this emulates writev */ * this emulates writev */
@ -1406,20 +1478,32 @@ ssl_handle_write(struct comm_point* c)
log_crypto_err("could not SSL_write"); log_crypto_err("could not SSL_write");
return 0; return 0;
} }
c->tcp_byte_count += r; if(c->tcp_write_and_read) {
if(c->tcp_byte_count < sizeof(uint16_t)) c->tcp_write_byte_count += r;
return 1; if(c->tcp_write_byte_count < sizeof(uint16_t))
sldns_buffer_set_position(c->buffer, c->tcp_byte_count - return 1;
sizeof(uint16_t)); } else {
if(sldns_buffer_remaining(c->buffer) == 0) { c->tcp_byte_count += r;
if(c->tcp_byte_count < sizeof(uint16_t))
return 1;
sldns_buffer_set_position(c->buffer, c->tcp_byte_count -
sizeof(uint16_t));
}
if((!c->tcp_write_and_read && sldns_buffer_remaining(c->buffer) == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == c->tcp_write_pkt_len + 2)) {
tcp_callback_writer(c); tcp_callback_writer(c);
return 1; return 1;
} }
} }
log_assert(sldns_buffer_remaining(c->buffer) > 0); log_assert(c->tcp_write_and_read || sldns_buffer_remaining(c->buffer) > 0);
log_assert(!c->tcp_write_and_read || c->tcp_write_byte_count < c->tcp_write_pkt_len + 2);
ERR_clear_error(); ERR_clear_error();
r = SSL_write(c->ssl, (void*)sldns_buffer_current(c->buffer), if(c->tcp_write_and_read) {
(int)sldns_buffer_remaining(c->buffer)); r = SSL_write(c->ssl, (void*)(c->tcp_write_pkt + c->tcp_write_byte_count - 2),
(int)(c->tcp_write_pkt_len + 2 - c->tcp_write_byte_count));
} else {
r = SSL_write(c->ssl, (void*)sldns_buffer_current(c->buffer),
(int)sldns_buffer_remaining(c->buffer));
}
if(r <= 0) { if(r <= 0) {
int want = SSL_get_error(c->ssl, r); int want = SSL_get_error(c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) { if(want == SSL_ERROR_ZERO_RETURN) {
@ -1444,9 +1528,13 @@ ssl_handle_write(struct comm_point* c)
log_crypto_err("could not SSL_write"); log_crypto_err("could not SSL_write");
return 0; return 0;
} }
sldns_buffer_skip(c->buffer, (ssize_t)r); if(c->tcp_write_and_read) {
c->tcp_write_byte_count += r;
} else {
sldns_buffer_skip(c->buffer, (ssize_t)r);
}
if(sldns_buffer_remaining(c->buffer) == 0) { if((!c->tcp_write_and_read && sldns_buffer_remaining(c->buffer) == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == c->tcp_write_pkt_len + 2)) {
tcp_callback_writer(c); tcp_callback_writer(c);
} }
return 1; return 1;
@ -1458,9 +1546,17 @@ ssl_handle_write(struct comm_point* c)
/** handle ssl tcp connection with dns contents */ /** handle ssl tcp connection with dns contents */
static int static int
ssl_handle_it(struct comm_point* c) ssl_handle_it(struct comm_point* c, int is_write)
{ {
if(c->tcp_is_reading) /* handle case where renegotiation wants read during write call
* or write during read calls */
if(is_write && c->ssl_shake_state == comm_ssl_shake_hs_write)
return ssl_handle_read(c);
else if(!is_write && c->ssl_shake_state == comm_ssl_shake_hs_read)
return ssl_handle_write(c);
/* handle read events for read operation and write events for a
* write operation */
else if(!is_write)
return ssl_handle_read(c); return ssl_handle_read(c);
return ssl_handle_write(c); return ssl_handle_write(c);
} }
@ -1477,8 +1573,8 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
ssize_t r; ssize_t r;
log_assert(c->type == comm_tcp || c->type == comm_local); log_assert(c->type == comm_tcp || c->type == comm_local);
if(c->ssl) if(c->ssl)
return ssl_handle_it(c); return ssl_handle_it(c, 0);
if(!c->tcp_is_reading) if(!c->tcp_is_reading && !c->tcp_write_and_read)
return 0; return 0;
log_assert(fd != -1); log_assert(fd != -1);
@ -1581,10 +1677,10 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#else #else
buffer = c->buffer; buffer = c->buffer;
#endif #endif
if(c->tcp_is_reading && !c->ssl) if(c->tcp_is_reading && !c->ssl && !c->tcp_write_and_read)
return 0; return 0;
log_assert(fd != -1); log_assert(fd != -1);
if(c->tcp_byte_count == 0 && c->tcp_check_nb_connect) { if(((!c->tcp_write_and_read && c->tcp_byte_count == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == 0)) && c->tcp_check_nb_connect) {
/* check for pending error from nonblocking connect */ /* check for pending error from nonblocking connect */
/* from Stevens, unix network programming, vol1, 3rd ed, p450*/ /* from Stevens, unix network programming, vol1, 3rd ed, p450*/
int error = 0; int error = 0;
@ -1625,7 +1721,7 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
} }
} }
if(c->ssl) if(c->ssl)
return ssl_handle_it(c); return ssl_handle_it(c, 1);
#ifdef USE_MSG_FASTOPEN #ifdef USE_MSG_FASTOPEN
/* Only try this on first use of a connection that uses tfo, /* Only try this on first use of a connection that uses tfo,
@ -1634,15 +1730,22 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(c->tcp_do_fastopen == 1) { if(c->tcp_do_fastopen == 1) {
/* this form of sendmsg() does both a connect() and send() so need to /* this form of sendmsg() does both a connect() and send() so need to
look for various flavours of error*/ look for various flavours of error*/
uint16_t len = htons(sldns_buffer_limit(buffer)); uint16_t len = htons(c->tcp_write_and_read?c->tcp_write_pkt_len:sldns_buffer_limit(buffer));
struct msghdr msg; struct msghdr msg;
struct iovec iov[2]; struct iovec iov[2];
c->tcp_do_fastopen = 0; c->tcp_do_fastopen = 0;
memset(&msg, 0, sizeof(msg)); memset(&msg, 0, sizeof(msg));
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count; if(c->tcp_write_and_read) {
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count; iov[0].iov_base = (uint8_t*)&len + c->tcp_write_byte_count;
iov[1].iov_base = sldns_buffer_begin(buffer); iov[0].iov_len = sizeof(uint16_t) - c->tcp_write_byte_count;
iov[1].iov_len = sldns_buffer_limit(buffer); iov[1].iov_base = c->tcp_write_pkt;
iov[1].iov_len = c->tcp_write_pkt_len;
} else {
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
iov[1].iov_base = sldns_buffer_begin(buffer);
iov[1].iov_len = sldns_buffer_limit(buffer);
}
log_assert(iov[0].iov_len > 0); log_assert(iov[0].iov_len > 0);
msg.msg_name = &c->repinfo.addr; msg.msg_name = &c->repinfo.addr;
msg.msg_namelen = c->repinfo.addrlen; msg.msg_namelen = c->repinfo.addrlen;
@ -1688,12 +1791,18 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
} }
} else { } else {
c->tcp_byte_count += r; if(c->tcp_write_and_read) {
if(c->tcp_byte_count < sizeof(uint16_t)) c->tcp_write_byte_count += r;
return 1; if(c->tcp_write_byte_count < sizeof(uint16_t))
sldns_buffer_set_position(buffer, c->tcp_byte_count - return 1;
sizeof(uint16_t)); } else {
if(sldns_buffer_remaining(buffer) == 0) { c->tcp_byte_count += r;
if(c->tcp_byte_count < sizeof(uint16_t))
return 1;
sldns_buffer_set_position(buffer, c->tcp_byte_count -
sizeof(uint16_t));
}
if((!c->tcp_write_and_read && sldns_buffer_remaining(buffer) == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == c->tcp_write_pkt_len + 2)) {
tcp_callback_writer(c); tcp_callback_writer(c);
return 1; return 1;
} }
@ -1701,19 +1810,31 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
} }
#endif /* USE_MSG_FASTOPEN */ #endif /* USE_MSG_FASTOPEN */
if(c->tcp_byte_count < sizeof(uint16_t)) { if((c->tcp_write_and_read?c->tcp_write_byte_count:c->tcp_byte_count) < sizeof(uint16_t)) {
uint16_t len = htons(sldns_buffer_limit(buffer)); uint16_t len = htons(c->tcp_write_and_read?c->tcp_write_pkt_len:sldns_buffer_limit(buffer));
#ifdef HAVE_WRITEV #ifdef HAVE_WRITEV
struct iovec iov[2]; struct iovec iov[2];
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count; if(c->tcp_write_and_read) {
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count; iov[0].iov_base = (uint8_t*)&len + c->tcp_write_byte_count;
iov[1].iov_base = sldns_buffer_begin(buffer); iov[0].iov_len = sizeof(uint16_t) - c->tcp_write_byte_count;
iov[1].iov_len = sldns_buffer_limit(buffer); iov[1].iov_base = c->tcp_write_pkt;
iov[1].iov_len = c->tcp_write_pkt_len;
} else {
iov[0].iov_base = (uint8_t*)&len + c->tcp_byte_count;
iov[0].iov_len = sizeof(uint16_t) - c->tcp_byte_count;
iov[1].iov_base = sldns_buffer_begin(buffer);
iov[1].iov_len = sldns_buffer_limit(buffer);
}
log_assert(iov[0].iov_len > 0); log_assert(iov[0].iov_len > 0);
r = writev(fd, iov, 2); r = writev(fd, iov, 2);
#else /* HAVE_WRITEV */ #else /* HAVE_WRITEV */
r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count), if(c->tcp_write_and_read) {
sizeof(uint16_t)-c->tcp_byte_count, 0); r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_write_byte_count),
sizeof(uint16_t)-c->tcp_write_byte_count, 0);
} else {
r = send(fd, (void*)(((uint8_t*)&len)+c->tcp_byte_count),
sizeof(uint16_t)-c->tcp_byte_count, 0);
}
#endif /* HAVE_WRITEV */ #endif /* HAVE_WRITEV */
if(r == -1) { if(r == -1) {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
@ -1752,19 +1873,31 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
#endif #endif
return 0; return 0;
} }
c->tcp_byte_count += r; if(c->tcp_write_and_read) {
if(c->tcp_byte_count < sizeof(uint16_t)) c->tcp_write_byte_count += r;
return 1; if(c->tcp_write_byte_count < sizeof(uint16_t))
sldns_buffer_set_position(buffer, c->tcp_byte_count - return 1;
sizeof(uint16_t)); } else {
if(sldns_buffer_remaining(buffer) == 0) { c->tcp_byte_count += r;
if(c->tcp_byte_count < sizeof(uint16_t))
return 1;
sldns_buffer_set_position(buffer, c->tcp_byte_count -
sizeof(uint16_t));
}
if((!c->tcp_write_and_read && sldns_buffer_remaining(buffer) == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == c->tcp_write_pkt_len + 2)) {
tcp_callback_writer(c); tcp_callback_writer(c);
return 1; return 1;
} }
} }
log_assert(sldns_buffer_remaining(buffer) > 0); log_assert(c->tcp_write_and_read || sldns_buffer_remaining(buffer) > 0);
r = send(fd, (void*)sldns_buffer_current(buffer), log_assert(!c->tcp_write_and_read || c->tcp_write_byte_count < c->tcp_write_pkt_len + 2);
sldns_buffer_remaining(buffer), 0); if(c->tcp_write_and_read) {
r = send(fd, (void*)c->tcp_write_pkt + c->tcp_write_byte_count - 2,
c->tcp_write_pkt_len + 2 - c->tcp_write_byte_count, 0);
} else {
r = send(fd, (void*)sldns_buffer_current(buffer),
sldns_buffer_remaining(buffer), 0);
}
if(r == -1) { if(r == -1) {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN) if(errno == EINTR || errno == EAGAIN)
@ -1787,9 +1920,13 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
&c->repinfo.addr, c->repinfo.addrlen); &c->repinfo.addr, c->repinfo.addrlen);
return 0; return 0;
} }
sldns_buffer_skip(buffer, r); if(c->tcp_write_and_read) {
c->tcp_write_byte_count += r;
} else {
sldns_buffer_skip(buffer, r);
}
if(sldns_buffer_remaining(buffer) == 0) { if((!c->tcp_write_and_read && sldns_buffer_remaining(buffer) == 0) || (c->tcp_write_and_read && c->tcp_write_byte_count == c->tcp_write_pkt_len + 2)) {
tcp_callback_writer(c); tcp_callback_writer(c);
} }
@ -1819,6 +1956,54 @@ tcp_req_info_read_again(int fd, struct comm_point* c)
} }
} }
/** read again to drain buffers when there could be more to read */
static void
tcp_more_read_again(int fd, struct comm_point* c)
{
/* if the packet is done, but another one could be waiting on
* the connection, the callback signals this, and we try again */
/* this continues until the read routines get EAGAIN or so,
* and thus does not call the callback, and the bool is 0 */
int* moreread = c->tcp_more_read_again;
while(moreread && *moreread) {
*moreread = 0;
if(!comm_point_tcp_handle_read(fd, c, 0)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point(
c->callback));
(void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL);
}
return;
}
}
}
/** write again to fill up when there could be more to write */
static void
tcp_more_write_again(int fd, struct comm_point* c)
{
/* if the packet is done, but another is waiting to be written,
* the callback signals it and we try again. */
/* this continues until the write routines get EAGAIN or so,
* and thus does not call the callback, and the bool is 0 */
int* morewrite = c->tcp_more_write_again;
while(morewrite && *morewrite) {
*morewrite = 0;
if(!comm_point_tcp_handle_write(fd, c)) {
reclaim_tcp_handler(c);
if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point(
c->callback));
(void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL);
}
return;
}
}
}
void void
comm_point_tcp_handle_callback(int fd, short event, void* arg) comm_point_tcp_handle_callback(int fd, short event, void* arg)
{ {
@ -1839,7 +2024,7 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
if(!c->tcp_do_close) { if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point( fptr_ok(fptr_whitelist_comm_point(
c->callback)); c->callback));
(void)(*c->callback)(c, c->cb_arg, (void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
return; return;
@ -1857,34 +2042,46 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
} }
return; return;
} }
if(event&UB_EV_READ) { if(event&UB_EV_READ
#ifdef USE_MSG_FASTOPEN
&& !(c->tcp_do_fastopen && (event&UB_EV_WRITE))
#endif
) {
int has_tcpq = (c->tcp_req_info != NULL); int has_tcpq = (c->tcp_req_info != NULL);
int* moreread = c->tcp_more_read_again;
if(!comm_point_tcp_handle_read(fd, c, 0)) { if(!comm_point_tcp_handle_read(fd, c, 0)) {
reclaim_tcp_handler(c); reclaim_tcp_handler(c);
if(!c->tcp_do_close) { if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point( fptr_ok(fptr_whitelist_comm_point(
c->callback)); c->callback));
(void)(*c->callback)(c, c->cb_arg, (void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
return;
} }
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
tcp_req_info_read_again(fd, c); tcp_req_info_read_again(fd, c);
if(moreread && *moreread)
tcp_more_read_again(fd, c);
return; return;
} }
if(event&UB_EV_WRITE) { if(event&UB_EV_WRITE) {
int has_tcpq = (c->tcp_req_info != NULL); int has_tcpq = (c->tcp_req_info != NULL);
int* morewrite = c->tcp_more_write_again;
if(!comm_point_tcp_handle_write(fd, c)) { if(!comm_point_tcp_handle_write(fd, c)) {
reclaim_tcp_handler(c); reclaim_tcp_handler(c);
if(!c->tcp_do_close) { if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point( fptr_ok(fptr_whitelist_comm_point(
c->callback)); c->callback));
(void)(*c->callback)(c, c->cb_arg, (void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
return;
} }
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
tcp_req_info_read_again(fd, c); tcp_req_info_read_again(fd, c);
if(morewrite && *morewrite)
tcp_more_write_again(fd, c);
return; return;
} }
log_err("Ignored event %d for tcphdl.", event); log_err("Ignored event %d for tcphdl.", event);
@ -2359,48 +2556,76 @@ int http2_stream_close_cb(nghttp2_session* ATTR_UNUSED(session),
ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf, ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
size_t len, int ATTR_UNUSED(flags), void* cb_arg) size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{ {
#ifdef HAVE_SSL
struct http2_session* h2_session = (struct http2_session*)cb_arg; struct http2_session* h2_session = (struct http2_session*)cb_arg;
int r; ssize_t ret;
log_assert(h2_session->c->type == comm_http); log_assert(h2_session->c->type == comm_http);
log_assert(h2_session->c->h2_session); log_assert(h2_session->c->h2_session);
if(!h2_session->c->ssl) #ifdef HAVE_SSL
return 0; if(h2_session->c->ssl) {
int r;
ERR_clear_error(); ERR_clear_error();
r = SSL_read(h2_session->c->ssl, buf, len); r = SSL_read(h2_session->c->ssl, buf, len);
if(r <= 0) { if(r <= 0) {
int want = SSL_get_error(h2_session->c->ssl, r); int want = SSL_get_error(h2_session->c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) { if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_EOF; return NGHTTP2_ERR_EOF;
} else if(want == SSL_ERROR_WANT_READ) { } else if(want == SSL_ERROR_WANT_READ) {
return NGHTTP2_ERR_WOULDBLOCK; return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_WANT_WRITE) { } else if(want == SSL_ERROR_WANT_WRITE) {
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_write; h2_session->c->ssl_shake_state = comm_ssl_shake_hs_write;
comm_point_listen_for_rw(h2_session->c, 0, 1); comm_point_listen_for_rw(h2_session->c, 0, 1);
return NGHTTP2_ERR_WOULDBLOCK; return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_SYSCALL) { } else if(want == SSL_ERROR_SYSCALL) {
#ifdef ECONNRESET #ifdef ECONNRESET
if(errno == ECONNRESET && verbosity < 2) if(errno == ECONNRESET && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif #endif
if(errno != 0) if(errno != 0)
log_err("SSL_read syscall: %s", log_err("SSL_read syscall: %s",
strerror(errno)); strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_read");
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} }
log_crypto_err("could not SSL_read"); return r;
}
#endif /* HAVE_SSL */
ret = recv(h2_session->c->fd, buf, len, 0);
if(ret == 0) {
return NGHTTP2_ERR_EOF;
} else if(ret < 0) {
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return NGHTTP2_ERR_WOULDBLOCK;
#ifdef ECONNRESET
if(errno == ECONNRESET && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif
log_err_addr("could not http2 recv: %s", strerror(errno),
&h2_session->c->repinfo.addr,
h2_session->c->repinfo.addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAECONNRESET)
return NGHTTP2_ERR_CALLBACK_FAILURE;
if(WSAGetLastError() == WSAEINPROGRESS)
return NGHTTP2_ERR_WOULDBLOCK;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
ub_winsock_tcp_wouldblock(h2_session->c->ev->ev,
UB_EV_READ);
return NGHTTP2_ERR_WOULDBLOCK;
}
log_err_addr("could not http2 recv: %s",
wsa_strerror(WSAGetLastError()),
&h2_session->c->repinfo.addr,
h2_session->c->repinfo.addrlen);
#endif
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} }
return r; return ret;
#else
(void)buf;
(void)len;
(void)cb_arg;
return -1;
#endif
} }
#endif /* HAVE_NGHTTP2 */ #endif /* HAVE_NGHTTP2 */
@ -2411,15 +2636,17 @@ comm_point_http2_handle_read(int ATTR_UNUSED(fd), struct comm_point* c)
#ifdef HAVE_NGHTTP2 #ifdef HAVE_NGHTTP2
int ret; int ret;
log_assert(c->h2_session); log_assert(c->h2_session);
log_assert(c->ssl);
/* reading until recv cb returns NGHTTP2_ERR_WOULDBLOCK */ /* reading until recv cb returns NGHTTP2_ERR_WOULDBLOCK */
ret = nghttp2_session_recv(c->h2_session->session); ret = nghttp2_session_recv(c->h2_session->session);
if(ret) { if(ret) {
if(ret != NGHTTP2_ERR_EOF && if(ret != NGHTTP2_ERR_EOF &&
ret != NGHTTP2_ERR_CALLBACK_FAILURE) { ret != NGHTTP2_ERR_CALLBACK_FAILURE) {
verbose(VERB_QUERY, "http2: session_recv failed, " char a[256];
"error: %s", nghttp2_strerror(ret)); addr_to_str(&c->repinfo.addr, c->repinfo.addrlen,
a, sizeof(a));
verbose(VERB_QUERY, "http2: session_recv from %s failed, "
"error: %s", a, nghttp2_strerror(ret));
} }
return 0; return 0;
} }
@ -2648,47 +2875,81 @@ http_write_more(int fd, struct comm_point* c)
ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf, ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
size_t len, int ATTR_UNUSED(flags), void* cb_arg) size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{ {
#ifdef HAVE_SSL ssize_t ret;
int r;
struct http2_session* h2_session = (struct http2_session*)cb_arg; struct http2_session* h2_session = (struct http2_session*)cb_arg;
log_assert(h2_session->c->type == comm_http); log_assert(h2_session->c->type == comm_http);
log_assert(h2_session->c->h2_session); log_assert(h2_session->c->h2_session);
if(!h2_session->c->ssl) #ifdef HAVE_SSL
return 0; if(h2_session->c->ssl) {
int r;
ERR_clear_error(); ERR_clear_error();
r = SSL_write(h2_session->c->ssl, buf, len); r = SSL_write(h2_session->c->ssl, buf, len);
if(r <= 0) { if(r <= 0) {
int want = SSL_get_error(h2_session->c->ssl, r); int want = SSL_get_error(h2_session->c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) { if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(want == SSL_ERROR_WANT_READ) {
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(h2_session->c, 1, 0);
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_WANT_WRITE) {
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef EPIPE
if(errno == EPIPE && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(want == SSL_ERROR_WANT_READ) {
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(h2_session->c, 1, 0);
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_WANT_WRITE) {
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef EPIPE
if(errno == EPIPE && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif #endif
if(errno != 0) if(errno != 0)
log_err("SSL_write syscall: %s", log_err("SSL_write syscall: %s",
strerror(errno)); strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_write");
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} }
log_crypto_err("could not SSL_write"); return r;
}
#endif /* HAVE_SSL */
ret = send(h2_session->c->fd, buf, len, 0);
if(ret == 0) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(ret < 0) {
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return NGHTTP2_ERR_WOULDBLOCK;
#ifdef EPIPE
if(errno == EPIPE && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif
#ifdef ECONNRESET
if(errno == ECONNRESET && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif
log_err_addr("could not http2 write: %s", strerror(errno),
&h2_session->c->repinfo.addr,
h2_session->c->repinfo.addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAENOTCONN)
return NGHTTP2_ERR_WOULDBLOCK;
if(WSAGetLastError() == WSAEINPROGRESS)
return NGHTTP2_ERR_WOULDBLOCK;
if(WSAGetLastError() == WSAEWOULDBLOCK) {
ub_winsock_tcp_wouldblock(h2_session->c->ev->ev,
UB_EV_WRITE);
return NGHTTP2_ERR_WOULDBLOCK;
}
if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
log_err_addr("could not http2 write: %s",
wsa_strerror(WSAGetLastError()),
&h2_session->c->repinfo.addr,
h2_session->c->repinfo.addrlen);
#endif
return NGHTTP2_ERR_CALLBACK_FAILURE; return NGHTTP2_ERR_CALLBACK_FAILURE;
} }
return r; return ret;
#else
(void)buf;
(void)len;
(void)cb_arg;
return -1;
#endif
} }
#endif /* HAVE_NGHTTP2 */ #endif /* HAVE_NGHTTP2 */
@ -2699,7 +2960,6 @@ comm_point_http2_handle_write(int ATTR_UNUSED(fd), struct comm_point* c)
#ifdef HAVE_NGHTTP2 #ifdef HAVE_NGHTTP2
int ret; int ret;
log_assert(c->h2_session); log_assert(c->h2_session);
log_assert(c->ssl);
ret = nghttp2_session_send(c->h2_session->session); ret = nghttp2_session_send(c->h2_session->session);
if(ret) { if(ret) {
@ -2811,7 +3071,7 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
if(!c->tcp_do_close) { if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point( fptr_ok(fptr_whitelist_comm_point(
c->callback)); c->callback));
(void)(*c->callback)(c, c->cb_arg, (void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
} }
@ -2823,7 +3083,7 @@ comm_point_http_handle_callback(int fd, short event, void* arg)
if(!c->tcp_do_close) { if(!c->tcp_do_close) {
fptr_ok(fptr_whitelist_comm_point( fptr_ok(fptr_whitelist_comm_point(
c->callback)); c->callback));
(void)(*c->callback)(c, c->cb_arg, (void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
} }
@ -3555,6 +3815,7 @@ comm_point_close(struct comm_point* c)
if(!c) if(!c)
return; return;
if(c->fd != -1) { if(c->fd != -1) {
verbose(5, "comm_point_close of %d: event_del", c->fd);
if(ub_event_del(c->ev->ev) != 0) { if(ub_event_del(c->ev->ev) != 0) {
log_err("could not event_del on close"); log_err("could not event_del on close");
} }
@ -3736,12 +3997,20 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
} }
if(c->type == comm_tcp || c->type == comm_http) { if(c->type == comm_tcp || c->type == comm_http) {
ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE); ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
if(c->tcp_is_reading) if(c->tcp_write_and_read) {
verbose(5, "startlistening %d mode rw", (newfd==-1?c->fd:newfd));
ub_event_add_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
} else if(c->tcp_is_reading) {
verbose(5, "startlistening %d mode r", (newfd==-1?c->fd:newfd));
ub_event_add_bits(c->ev->ev, UB_EV_READ); ub_event_add_bits(c->ev->ev, UB_EV_READ);
else ub_event_add_bits(c->ev->ev, UB_EV_WRITE); } else {
verbose(5, "startlistening %d mode w", (newfd==-1?c->fd:newfd));
ub_event_add_bits(c->ev->ev, UB_EV_WRITE);
}
} }
if(newfd != -1) { if(newfd != -1) {
if(c->fd != -1) { if(c->fd != -1 && c->fd != newfd) {
verbose(5, "cpsl close of fd %d for %d", c->fd, newfd);
sock_close(c->fd); sock_close(c->fd);
} }
c->fd = newfd; c->fd = newfd;

View File

@ -95,6 +95,9 @@ typedef int comm_point_callback_type(struct comm_point*, void*, int,
#define NETEVENT_CAPSFAIL -3 #define NETEVENT_CAPSFAIL -3
/** to pass done transfer to callback function; http file is complete */ /** to pass done transfer to callback function; http file is complete */
#define NETEVENT_DONE -4 #define NETEVENT_DONE -4
/** to pass write of the write packet is done to callback function
* used when tcp_write_and_read is enabled */
#define NETEVENT_PKT_WRITTEN -5
/** timeout to slow accept calls when not possible, in msec. */ /** timeout to slow accept calls when not possible, in msec. */
#define NETEVENT_SLOW_ACCEPT_TIME 2000 #define NETEVENT_SLOW_ACCEPT_TIME 2000
@ -276,6 +279,44 @@ struct comm_point {
and after read/write completes. No callback is done. */ and after read/write completes. No callback is done. */
int tcp_do_close; int tcp_do_close;
/** flag that indicates the stream is both written and read from. */
int tcp_write_and_read;
/** byte count for written length over write channel, for when
* tcp_write_and_read is enabled. When tcp_write_and_read is enabled,
* this is the counter for writing, the one for reading is in the
* commpoint.buffer sldns buffer. The counter counts from 0 to
* 2+tcp_write_pkt_len, and includes the tcp length bytes. */
size_t tcp_write_byte_count;
/** packet to write currently over the write channel. for when
* tcp_write_and_read is enabled. When tcp_write_and_read is enabled,
* this is the buffer for the written packet, the commpoint.buffer
* sldns buffer is the buffer for the received packet. */
uint8_t* tcp_write_pkt;
/** length of tcp_write_pkt in bytes */
size_t tcp_write_pkt_len;
/** if set try to read another packet again (over connection with
* multiple packets), once set, tries once, then zero again,
* so set it in the packet complete section.
* The pointer itself has to be set before the callback is invoked,
* when you set things up, and continue to exist also after the
* commpoint is closed and deleted in your callback. So that after
* the callback cleans up netevent can see what it has to do.
* Or leave NULL if it is not used at all. */
int* tcp_more_read_again;
/** if set try to write another packet (over connection with
* multiple packets), once set, tries once, then zero again,
* so set it in the packet complete section.
* The pointer itself has to be set before the callback is invoked,
* when you set things up, and continue to exist also after the
* commpoint is closed and deleted in your callback. So that after
* the callback cleans up netevent can see what it has to do.
* Or leave NULL if it is not used at all. */
int* tcp_more_write_again;
/** if set, read/write completes: /** if set, read/write completes:
read/write state of tcp is toggled. read/write state of tcp is toggled.
buffer reset/bytecount reset. buffer reset/bytecount reset.
@ -589,7 +630,8 @@ void comm_point_drop_reply(struct comm_reply* repinfo);
* Send an udp message over a commpoint. * Send an udp message over a commpoint.
* @param c: commpoint to send it from. * @param c: commpoint to send it from.
* @param packet: what to send. * @param packet: what to send.
* @param addr: where to send it to. * @param addr: where to send it to. If NULL, send is performed,
* for connected sockets, to the connected address.
* @param addrlen: length of addr. * @param addrlen: length of addr.
* @return: false on a failure. * @return: false on a failure.
*/ */

View File

@ -80,18 +80,39 @@ regional_init(struct regional* r)
r->total_large = 0; r->total_large = 0;
} }
struct regional* /**
regional_create_custom(size_t size) * Create a new region, with custom first block and large-object sizes.
* @param size: length of first block.
* @param large_object_size: outside of chunk allocation threshold.
* @return: newly allocated regional.
*/
static struct regional*
regional_create_custom_large_object(size_t size, size_t large_object_size)
{ {
struct regional* r = (struct regional*)malloc(size); struct regional* r;
size = ALIGN_UP(size, ALIGNMENT); size = ALIGN_UP(size, ALIGNMENT);
r = (struct regional*)malloc(size);
log_assert(sizeof(struct regional) <= size); log_assert(sizeof(struct regional) <= size);
if(!r) return NULL; if(!r) return NULL;
r->first_size = size; r->first_size = size;
r->large_object_size = large_object_size;
regional_init(r); regional_init(r);
return r; return r;
} }
struct regional*
regional_create_custom(size_t size)
{
return regional_create_custom_large_object(size,
REGIONAL_LARGE_OBJECT_SIZE);
}
struct regional*
regional_create_nochunk(size_t size)
{
return regional_create_custom_large_object(size, 0);
}
void void
regional_free_all(struct regional *r) regional_free_all(struct regional *r)
{ {
@ -134,7 +155,7 @@ regional_alloc(struct regional *r, size_t size)
malloc and ALIGN_UP */ malloc and ALIGN_UP */
a = ALIGN_UP(size, ALIGNMENT); a = ALIGN_UP(size, ALIGNMENT);
/* large objects */ /* large objects */
if(a > REGIONAL_LARGE_OBJECT_SIZE) { if(a > r->large_object_size) {
s = malloc(ALIGNMENT + size); s = malloc(ALIGNMENT + size);
if(!s) return NULL; if(!s) return NULL;
r->total_large += ALIGNMENT+size; r->total_large += ALIGNMENT+size;
@ -219,7 +240,7 @@ regional_log_stats(struct regional *r)
/* some basic assertions put here (non time critical code) */ /* some basic assertions put here (non time critical code) */
log_assert(ALIGNMENT >= sizeof(char*)); log_assert(ALIGNMENT >= sizeof(char*));
log_assert(REGIONAL_CHUNK_SIZE > ALIGNMENT); log_assert(REGIONAL_CHUNK_SIZE > ALIGNMENT);
log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > REGIONAL_LARGE_OBJECT_SIZE); log_assert(REGIONAL_CHUNK_SIZE-ALIGNMENT > r->large_object_size);
log_assert(REGIONAL_CHUNK_SIZE >= sizeof(struct regional)); log_assert(REGIONAL_CHUNK_SIZE >= sizeof(struct regional));
/* debug print */ /* debug print */
log_info("regional %u chunks, %u large", log_info("regional %u chunks, %u large",

View File

@ -74,6 +74,11 @@ struct regional
size_t available; size_t available;
/** current chunk data position. */ /** current chunk data position. */
char* data; char* data;
/** threshold for outside of chunk allocations */
size_t large_object_size;
/** padding for sizeof8 alignment of sizeof(struct regional)
* for 32bit systems */
size_t padding;
}; };
/** /**
@ -88,6 +93,14 @@ struct regional* regional_create(void);
* @return: newly allocated regional. * @return: newly allocated regional.
*/ */
struct regional* regional_create_custom(size_t size); struct regional* regional_create_custom(size_t size);
/**
* Create a new region, with custom settings, that will allocate everything
* outside the region chunk.
* @param size: length of first block.
* @return: newly allocated regional.
*/
struct regional* regional_create_nochunk(size_t size);
/** /**
* Free all memory associated with regional. Only keeps the first block with * Free all memory associated with regional. Only keeps the first block with

View File

@ -990,6 +990,7 @@ static SECKEYPublicKey* nss_buf2ecdsa(unsigned char* key, size_t len, int algo)
return pk; return pk;
} }
#if defined(USE_DSA) && defined(USE_SHA1)
static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len) static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
{ {
SECKEYPublicKey* pk; SECKEYPublicKey* pk;
@ -1050,6 +1051,7 @@ static SECKEYPublicKey* nss_buf2dsa(unsigned char* key, size_t len)
} }
return pk; return pk;
} }
#endif /* USE_DSA && USE_SHA1 */
static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len) static SECKEYPublicKey* nss_buf2rsa(unsigned char* key, size_t len)
{ {