From 7954be7fa5ea70de36aacebb8bcca2a70af709f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 2 Jan 2015 17:35:29 +0000 Subject: [PATCH] import unbound 1.5.1 --- Makefile.in | 4 +- compat/arc4_lock.c | 4 +- compat/getentropy_linux.c | 11 +- compat/getentropy_win.c | 4 +- config.h.in | 3 - configure | 1429 +--------------------------- configure.ac | 36 +- contrib/README | 4 + contrib/aaaa-filter-iterator.patch | 394 ++++++++ daemon/cachedump.c | 2 +- daemon/remote.c | 10 +- daemon/unbound.c | 2 +- daemon/worker.c | 2 +- dns64/dns64.c | 8 +- doc/Changelog | 60 ++ doc/README | 2 +- doc/example.conf.in | 2 +- doc/libunbound.3.in | 4 +- doc/unbound-anchor.8.in | 8 +- doc/unbound-checkconf.8.in | 2 +- doc/unbound-control.8.in | 2 +- doc/unbound-host.1.in | 2 +- doc/unbound.8.in | 4 +- doc/unbound.conf.5.in | 2 +- iterator/iter_utils.c | 7 +- iterator/iter_utils.h | 3 +- iterator/iterator.c | 71 +- iterator/iterator.h | 6 + libunbound/unbound.h | 2 +- pythonmod/pythonmod_utils.c | 4 +- services/cache/dns.c | 34 +- services/cache/dns.h | 9 +- services/mesh.c | 43 +- services/mesh.h | 13 +- smallapp/unbound-host.c | 2 +- util/data/msgreply.c | 13 +- util/data/msgreply.h | 5 +- util/fptr_wlist.c | 4 +- util/fptr_wlist.h | 4 +- util/iana_ports.inc | 3 + util/module.h | 10 +- util/net_help.c | 2 +- validator/validator.c | 31 +- 43 files changed, 705 insertions(+), 1562 deletions(-) create mode 100644 contrib/aaaa-filter-iterator.patch diff --git a/Makefile.in b/Makefile.in index 7300b3e3476..02532a951d2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -80,7 +80,7 @@ LINTFLAGS+="-Dsigset_t=long" # FreeBSD LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" -INSTALL=$(srcdir)/install-sh +INSTALL=$(SHELL) $(srcdir)/install-sh #pythonmod.c is not here, it is mentioned by itself in its own rules, #makedepend fails on missing interface.h otherwise. @@ -397,7 +397,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i un # Pyunbound python unbound wrapper _unbound.la: libunbound_wrap.lo libunbound.la - $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS) + $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h diff --git a/compat/arc4_lock.c b/compat/arc4_lock.c index ce8bb4168d6..faa743d15ba 100644 --- a/compat/arc4_lock.c +++ b/compat/arc4_lock.c @@ -53,8 +53,10 @@ static int arc4lockinit = 0; void _ARC4_LOCK(void) { - if(!arc4lockinit) + if(!arc4lockinit) { + arc4lockinit = 1; lock_quick_init(&arc4lock); + } lock_quick_lock(&arc4lock); } diff --git a/compat/getentropy_linux.c b/compat/getentropy_linux.c index d51d7952d8c..32d58a7cdbb 100644 --- a/compat/getentropy_linux.c +++ b/compat/getentropy_linux.c @@ -48,6 +48,7 @@ #include #include +#include #include #include #ifdef HAVE_GETAUXVAL @@ -77,7 +78,7 @@ extern int main(int, char *argv[]); #endif static int gotdata(char *buf, size_t len); static int getentropy_urandom(void *buf, size_t len); -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl static int getentropy_sysctl(void *buf, size_t len); #endif static int getentropy_fallback(void *buf, size_t len); @@ -102,7 +103,7 @@ getentropy(void *buf, size_t len) if (ret != -1) return (ret); -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl /* * Try to use sysctl CTL_KERN, KERN_RANDOM, RANDOM_UUID. * sysctl is a failsafe API, so it guarantees a result. This @@ -124,7 +125,7 @@ getentropy(void *buf, size_t len) ret = getentropy_sysctl(buf, len); if (ret != -1) return (ret); -#endif /* CTL_MAXNAME */ +#endif /* SYS__sysctl */ /* * Entropy collection via /dev/urandom and sysctl have failed. @@ -235,7 +236,7 @@ nodevrandom: return -1; } -#ifdef CTL_MAXNAME +#ifdef SYS__sysctl static int getentropy_sysctl(void *buf, size_t len) { @@ -265,7 +266,7 @@ sysctlfailed: errno = EIO; return -1; } -#endif /* CTL_MAXNAME */ +#endif /* SYS__sysctl */ static int cl[] = { CLOCK_REALTIME, diff --git a/compat/getentropy_win.c b/compat/getentropy_win.c index 9dc55891e39..71fb955e7f9 100644 --- a/compat/getentropy_win.c +++ b/compat/getentropy_win.c @@ -41,9 +41,9 @@ getentropy(void *buf, size_t len) } if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT) != 0) + CRYPT_VERIFYCONTEXT) == 0) goto fail; - if (CryptGenRandom(provider, len, buf) != 0) { + if (CryptGenRandom(provider, len, buf) == 0) { CryptReleaseContext(provider, 0); goto fail; } diff --git a/config.h.in b/config.h.in index 5f8f8a992de..2b7770b5c23 100644 --- a/config.h.in +++ b/config.h.in @@ -1,8 +1,5 @@ /* config.h.in. Generated from configure.ac by autoheader. */ -/* define if a library can reference the 'main' symbol */ -#undef CAN_REFERENCE_MAIN - /* Directory to chroot to */ #undef CHROOT_DIR diff --git a/configure b/configure index 32ad5f4f3cc..bdfc14f2205 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for unbound 1.5.0. +# Generated by GNU Autoconf 2.69 for unbound 1.5.1. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.5.0' -PACKAGE_STRING='unbound 1.5.0' +PACKAGE_VERSION='1.5.1' +PACKAGE_STRING='unbound 1.5.1' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl' PACKAGE_URL='' @@ -1387,7 +1387,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures unbound 1.5.0 to adapt to many kinds of systems. +\`configure' configures unbound 1.5.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1452,7 +1452,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.5.0:";; + short | recursive ) echo "Configuration of unbound 1.5.1:";; esac cat <<\_ACEOF @@ -1627,7 +1627,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.5.0 +unbound configure 1.5.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2336,7 +2336,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.5.0, which was +It was created by unbound $as_me 1.5.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2688,7 +2688,7 @@ UNBOUND_VERSION_MAJOR=1 UNBOUND_VERSION_MINOR=5 -UNBOUND_VERSION_MICRO=0 +UNBOUND_VERSION_MICRO=1 LIBUNBOUND_CURRENT=5 @@ -2732,6 +2732,7 @@ LIBUNBOUND_AGE=3 # 1.4.21 had 4:1:2 # 1.4.22 had 4:1:2 # 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr +# 1.5.1 had 5:4:3 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -18312,1411 +18313,6 @@ fi ;; esac - # generate libtool to test if linking main - # from a dynamic library works. - : ${CONFIG_LT=./config.lt} -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_LT" >&5 -$as_echo "$as_me: creating $CONFIG_LT" >&6;} -as_write_fail=0 -cat >"$CONFIG_LT" <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate a libtool stub with the current configuration. -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>"$CONFIG_LT" <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## --------------------------------- ## -## Main body of "$CONFIG_LT" script. ## -## --------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x "$CONFIG_LT" - -cat >>"$CONFIG_LT" <<\_LTEOF -lt_cl_silent=false -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX -} >&5 - -lt_cl_help="\ -\`$as_me' creates a local libtool stub from the current configuration, -for use in further configure time tests before the real libtool is -generated. - -Usage: $0 [OPTIONS] - - -h, --help print this help, then exit - -V, --version print version number, then exit - -q, --quiet do not print progress messages - -d, --debug don't remove temporary files - -Report bugs to ." - -lt_cl_version="\ -unbound config.lt 1.5.0 -configured by $0, generated by GNU Autoconf 2.69. - -Copyright (C) 2011 Free Software Foundation, Inc. -This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." - -while test $# != 0 -do - case $1 in - --version | --v* | -V ) - echo "$lt_cl_version"; exit 0 ;; - --help | --h* | -h ) - echo "$lt_cl_help"; exit 0 ;; - --debug | --d* | -d ) - debug=: ;; - --quiet | --q* | --silent | --s* | -q ) - lt_cl_silent=: ;; - - -*) as_fn_error $? "unrecognized option: $1 -Try \`$0 --help' for more information." "$LINENO" 5 ;; - - *) as_fn_error $? "unrecognized argument: $1 -Try \`$0 --help' for more information." "$LINENO" 5 ;; - esac - shift -done - -if $lt_cl_silent; then - exec 6>/dev/null -fi -_LTEOF - -cat >>"$CONFIG_LT" <<_LTEOF - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' -macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' -enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' -enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' -pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' -SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' -ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' -PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' -host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' -host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' -host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' -build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' -build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' -build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' -SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' -Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' -GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' -EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' -FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' -LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' -NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' -LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' -ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' -exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' -lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' -lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' -lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' -reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' -file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' -want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' -DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' -sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' -AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' -archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' -STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' -RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' -lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' -CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' -compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' -GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' -nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' -lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' -objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' -need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' -MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' -LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' -OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' -libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' -module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' -postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' -need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' -version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' -runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' -libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' -soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' -install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' -finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' -old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' -striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# A function that is used when there is no print builtin or printf. -func_fallback_echo () -{ - eval 'cat <<_LTECHO_EOF -\$1 -_LTECHO_EOF' -} - -# Quote evaled strings. -for var in SHELL \ -ECHO \ -PATH_SEPARATOR \ -SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -file_magic_glob \ -want_nocaseglob \ -DLLTOOL \ -sharedlib_from_linklib_cmd \ -AR \ -AR_FLAGS \ -archiver_list_spec \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -nm_file_list_spec \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_pic \ -lt_prog_compiler_wl \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -MANIFEST_TOOL \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_separator \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -install_override_mode \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postlink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - -_LTEOF - -cat >>"$CONFIG_LT" <<\_LTEOF -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ofile" >&5 -$as_echo "$as_me: creating $ofile" >&6;} - - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that protects backslashes. -ECHO=$lt_ECHO - -# The PATH separator for the build system. -PATH_SEPARATOR=$lt_PATH_SEPARATOR - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# convert \$build file names to \$host format. -to_host_file_cmd=$lt_cv_to_host_file_cmd - -# convert \$build files to toolchain format. -to_tool_file_cmd=$lt_cv_to_tool_file_cmd - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method = "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# How to find potential files when deplibs_check_method = "file_magic". -file_magic_glob=$lt_file_magic_glob - -# Find potential files using nocaseglob when deplibs_check_method = "file_magic". -want_nocaseglob=$lt_want_nocaseglob - -# DLL creation program. -DLLTOOL=$lt_DLLTOOL - -# Command to associate shared and link libraries. -sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd - -# The archiver. -AR=$lt_AR - -# Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS - -# How to feed a file listing to the archiver. -archiver_list_spec=$lt_archiver_list_spec - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Whether to use a lock for old archive extraction. -lock_old_archive_extraction=$lock_old_archive_extraction - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# Specify filename containing input files for \$NM. -nm_file_list_spec=$lt_nm_file_list_spec - -# The root where to search for dependent libraries,and in which our libraries should be installed. -lt_sysroot=$lt_sysroot - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Manifest tool. -MANIFEST_TOOL=$lt_MANIFEST_TOOL - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Permission mode override for installation of shared libraries. -install_override_mode=$lt_install_override_mode - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Commands necessary for finishing linking programs. -postlink_cmds=$lt_postlink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - if test x"$xsi_shell" = xyes; then - sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ -func_dirname ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_basename ()$/,/^} # func_basename /c\ -func_basename ()\ -{\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ -func_dirname_and_basename ()\ -{\ -\ case ${1} in\ -\ */*) func_dirname_result="${1%/*}${2}" ;;\ -\ * ) func_dirname_result="${3}" ;;\ -\ esac\ -\ func_basename_result="${1##*/}"\ -} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ -func_stripname ()\ -{\ -\ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ -\ # positional parameters, so assign one to ordinary parameter first.\ -\ func_stripname_result=${3}\ -\ func_stripname_result=${func_stripname_result#"${1}"}\ -\ func_stripname_result=${func_stripname_result%"${2}"}\ -} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ -func_split_long_opt ()\ -{\ -\ func_split_long_opt_name=${1%%=*}\ -\ func_split_long_opt_arg=${1#*=}\ -} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ -func_split_short_opt ()\ -{\ -\ func_split_short_opt_arg=${1#??}\ -\ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ -} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ -func_lo2o ()\ -{\ -\ case ${1} in\ -\ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ -\ *) func_lo2o_result=${1} ;;\ -\ esac\ -} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_xform ()$/,/^} # func_xform /c\ -func_xform ()\ -{\ - func_xform_result=${1%.*}.lo\ -} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_arith ()$/,/^} # func_arith /c\ -func_arith ()\ -{\ - func_arith_result=$(( $* ))\ -} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_len ()$/,/^} # func_len /c\ -func_len ()\ -{\ - func_len_result=${#1}\ -} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - -fi - -if test x"$lt_shell_append" = xyes; then - sed -e '/^func_append ()$/,/^} # func_append /c\ -func_append ()\ -{\ - eval "${1}+=\\${2}"\ -} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ -func_append_quoted ()\ -{\ -\ func_quote_for_eval "${2}"\ -\ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ -} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") -test 0 -eq $? || _lt_function_replace_fail=: - - - # Save a `func_append' function call where possible by direct use of '+=' - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -else - # Save a `func_append' function call even when '+=' is not available - sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ - && mv -f "$cfgfile.tmp" "$cfgfile" \ - || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") - test 0 -eq $? || _lt_function_replace_fail=: -fi - -if test x"$_lt_function_replace_fail" = x":"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 -$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} -fi - - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - -as_fn_exit 0 -_LTEOF -chmod +x "$CONFIG_LT" - -# configure is writing to config.log, but config.lt does its own redirection, -# appending to config.log, which fails on DOS, as config.log is still kept -# open by configure. Here we exec the FD to /dev/null, effectively closing -# config.log, so it can be properly (re)opened and appended to by config.lt. -lt_cl_success=: -test "$silent" = yes && - lt_config_lt_args="$lt_config_lt_args --quiet" -exec 5>/dev/null -$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false -exec 5>>config.log -$lt_cl_success || as_fn_exit 1 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if dynamic lib can refer to main" >&5 -$as_echo_n "checking if dynamic lib can refer to main... " >&6; } - cat >tmp.$$.def <tmp.$$.c </dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - if test "$myok" = "yes"; then - $mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - fi - if test "$myok" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - -$as_echo "#define CAN_REFERENCE_MAIN 1" >>confdefs.h - - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - $mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo - rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o - fi fi @@ -20156,7 +18752,7 @@ _ACEOF -version=1.5.0 +version=1.5.1 date=`date +'%b %e, %Y'` @@ -20671,7 +19267,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.5.0, which was +This file was extended by unbound $as_me 1.5.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -20737,7 +19333,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -unbound config.status 1.5.0 +unbound config.status 1.5.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -21129,7 +19725,6 @@ fi RM='$RM' ofile='$ofile' -ac_aux_dir='$ac_aux_dir' diff --git a/configure.ac b/configure.ac index 63a60b428a9..7e5da1a9f04 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ sinclude(dnstap/dnstap.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MINOR],[5]) -m4_define([VERSION_MICRO],[0]) +m4_define([VERSION_MICRO],[1]) AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) @@ -57,6 +57,7 @@ LIBUNBOUND_AGE=3 # 1.4.21 had 4:1:2 # 1.4.22 had 4:1:2 # 1.5.0 had 5:3:3 # adds ub_ctx_add_ta_autr +# 1.5.1 had 5:4:3 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -1022,39 +1023,6 @@ if test "$USE_NSS" = "no"; then AC_SEARCH_LIBS([clock_gettime], [rt]) ;; esac - # generate libtool to test if linking main - # from a dynamic library works. - LT_OUTPUT - AC_MSG_CHECKING([if dynamic lib can refer to main]) - cat >tmp.$$.def <tmp.$$.c </dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - if test "$myok" = "yes"; then - $mylibtool --quiet --tag=CC --mode=link $CC $CFLAGS -version-info 1:0:0 -no-undefined -export-symbols tmp.$$.def -o libtmp$$.la tmp.$$.lo $LDFLAGS -rpath $mylibdir $LIBS >/dev/null 2>&1 - if test $? = 0; then myok=yes; else myok=no; fi - fi - if test "$myok" = "yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(CAN_REFERENCE_MAIN, [1], [define if a library can reference the 'main' symbol]) - else - AC_MSG_RESULT(no) - fi - $mylibtool --quiet --mode=clean rm -rf libtmp$$.la tmp.$$.lo - rm -f tmp.$$.def tmp.$$.c libtmp$$.la tmp.$$.lo tmp.$$.o - fi ]) fi diff --git a/contrib/README b/contrib/README index efbffbd0c56..49dee02e514 100644 --- a/contrib/README +++ b/contrib/README @@ -25,4 +25,8 @@ distribution but may be helpful. * unbound_cache.cmd: windows script to save and load the cache. * warmup.sh: shell script to warm up DNS cache by your own MRU domains. * warmup.cmd: windows script to warm up DNS cache by your own MRU domains. +* aaaa-filter-iterator.patch: adds config option aaaa-filter: yes that + works like the BIND feature (removes AAAA records unless AAAA-only domain). + Useful for certain 'broken IPv6 default route' scenarios. + Patch from Stephane Lapie for ASAHI Net. diff --git a/contrib/aaaa-filter-iterator.patch b/contrib/aaaa-filter-iterator.patch new file mode 100644 index 00000000000..8e03d7c99ac --- /dev/null +++ b/contrib/aaaa-filter-iterator.patch @@ -0,0 +1,394 @@ +--- unbound-1.4.17.orig/doc/unbound.conf.5.in ++++ unbound-1.4.17/doc/unbound.conf.5.in +@@ -519,6 +519,13 @@ authority servers and checks if the repl + Disabled by default. + This feature is an experimental implementation of draft dns\-0x20. + .TP ++.B aaaa\-filter: \fI ++Activate behavior similar to BIND's AAAA-filter. ++This forces the dropping of all AAAA records, unless in the case of ++explicit AAAA queries, when no A records have been confirmed. ++This also causes an additional A query to be sent for each AAAA query. ++This breaks DNSSEC! ++.TP + .B private\-address: \fI + Give IPv4 of IPv6 addresses or classless subnets. These are addresses + on your private network, and are not allowed to be returned for public +--- unbound-1.4.17.orig/util/config_file.c ++++ unbound-1.4.17/util/config_file.c +@@ -160,6 +160,7 @@ config_create(void) + cfg->harden_below_nxdomain = 0; + cfg->harden_referral_path = 0; + cfg->use_caps_bits_for_id = 0; ++ cfg->aaaa_filter = 0; /* ASN: default is disabled */ + cfg->private_address = NULL; + cfg->private_domain = NULL; + cfg->unwanted_threshold = 0; +--- unbound-1.4.17.orig/iterator/iter_scrub.c ++++ unbound-1.4.17/iterator/iter_scrub.c +@@ -580,6 +580,32 @@ static int sanitize_nsec_is_overreach(st + } + + /** ++ * ASN: Lookup A records from rrset cache. ++ * @param qinfo: the question originally asked. ++ * @param env: module environment with config and cache. ++ * @param ie: iterator environment with private address data. ++ * @return 0 if no A record found, 1 if A record found. ++ */ ++static int ++asn_lookup_a_record_from_cache(struct query_info* qinfo, ++ struct module_env* env, struct iter_env* ie) ++{ ++ struct ub_packed_rrset_key* akey; ++ ++ /* get cached A records for queried name */ ++ akey = rrset_cache_lookup(env->rrset_cache, qinfo->qname, ++ qinfo->qname_len, LDNS_RR_TYPE_A, qinfo->qclass, ++ 0, *env->now, 0); ++ if(akey) { /* we had some. */ ++ log_rrset_key(VERB_ALGO, "ASN-AAAA-filter: found A record", ++ akey); ++ lock_rw_unlock(&akey->entry.lock); ++ return 1; ++ } ++ return 0; ++} ++ ++/** + * Given a response event, remove suspect RRsets from the response. + * "Suspect" rrsets are potentially poison. Note that this routine expects + * the response to be in a "normalized" state -- that is, all "irrelevant" +@@ -598,6 +625,7 @@ scrub_sanitize(ldns_buffer* pkt, struct + struct query_info* qinfo, uint8_t* zonename, struct module_env* env, + struct iter_env* ie) + { ++ int found_a_record = 0; /* ASN: do we have a A record? */ + int del_addi = 0; /* if additional-holding rrsets are deleted, we + do not trust the normalized additional-A-AAAA any more */ + struct rrset_parse* rrset, *prev; +@@ -633,6 +661,13 @@ scrub_sanitize(ldns_buffer* pkt, struct + rrset = rrset->rrset_all_next; + } + ++ /* ASN: Locate any A record we can find */ ++ if((ie->aaaa_filter) && (qinfo->qtype == LDNS_RR_TYPE_AAAA)) { ++ found_a_record = asn_lookup_a_record_from_cache(qinfo, ++ env, ie); ++ } ++ /* ASN: End of added code */ ++ + /* At this point, we brutally remove ALL rrsets that aren't + * children of the originating zone. The idea here is that, + * as far as we know, the server that we contacted is ONLY +@@ -644,6 +679,24 @@ scrub_sanitize(ldns_buffer* pkt, struct + rrset = msg->rrset_first; + while(rrset) { + ++ /* ASN: For AAAA records only... */ ++ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) { ++ /* ASN: If this is not a AAAA query, then remove AAAA ++ * records, no questions asked. If this IS a AAAA query ++ * then remove AAAA records if we have an A record. ++ * Otherwise, leave things be. */ ++ if((qinfo->qtype != LDNS_RR_TYPE_AAAA) || ++ (found_a_record)) { ++ remove_rrset("ASN-AAAA-filter: removing AAAA " ++ "for record", pkt, msg, prev, &rrset); ++ continue; ++ } ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: " ++ "keep AAAA for", zonename, ++ LDNS_RR_TYPE_AAAA, qinfo->qclass); ++ } ++ /* ASN: End of added code */ ++ + /* remove private addresses */ + if( (rrset->type == LDNS_RR_TYPE_A || + rrset->type == LDNS_RR_TYPE_AAAA) && +--- unbound-1.4.17.orig/iterator/iterator.c ++++ unbound-1.4.17/iterator/iterator.c +@@ -1579,6 +1579,53 @@ processDSNSFind(struct module_qstate* qs + + return 0; + } ++ ++/** ++ * ASN: This event state was added as an intermediary step between ++ * QUERYTARGETS_STATE and the next step, in order to cast a subquery for the ++ * purpose of caching A records for the queried name. ++ * ++ * @param qstate: query state. ++ * @param iq: iterator query state. ++ * @param ie: iterator shared global environment. ++ * @param id: module id. ++ * @return true if the event requires more request processing immediately, ++ * false if not. This state only returns true when it is generating ++ * a SERVFAIL response because the query has hit a dead end. ++ */ ++static int ++asn_processQueryAAAA(struct module_qstate* qstate, struct iter_qstate* iq, ++ struct iter_env* ie, int id) ++{ ++ struct module_qstate* subq = NULL; ++ ++ log_assert(iq->fetch_a_for_aaaa == 0); ++ ++ /* flag the query properly in order to not loop */ ++ iq->fetch_a_for_aaaa = 1; ++ ++ /* re-throw same query, but with a different type */ ++ if(!generate_sub_request(iq->qchase.qname, ++ iq->qchase.qname_len, LDNS_RR_TYPE_A, ++ iq->qchase.qclass, qstate, id, iq, ++ INIT_REQUEST_STATE, FINISHED_STATE, &subq, 1)) { ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: failed " ++ "preloading of A record for", ++ iq->qchase.qname, LDNS_RR_TYPE_A, ++ iq->qchase.qclass); ++ return error_response(qstate, id, LDNS_RCODE_SERVFAIL); ++ } ++ log_nametypeclass(VERB_ALGO, "ASN-AAAA-filter: " ++ "preloading records in cache for", ++ iq->qchase.qname, LDNS_RR_TYPE_A, ++ iq->qchase.qclass); ++ ++ /* set this query as waiting */ ++ qstate->ext_state[id] = module_wait_subquery; ++ /* at this point break loop */ ++ return 0; ++} ++/* ASN: End of added code */ + + /** + * This is the request event state where the request will be sent to one of +@@ -1626,6 +1673,13 @@ processQueryTargets(struct module_qstate + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + } + ++ /* ASN: If we have a AAAA query, then also query for A records */ ++ if((ie->aaaa_filter) && (iq->qchase.qtype == LDNS_RR_TYPE_AAAA) && ++ (iq->fetch_a_for_aaaa == 0)) { ++ return next_state(iq, ASN_FETCH_A_FOR_AAAA_STATE); ++ } ++ /* ASN: End of added code */ ++ + /* Make sure we have a delegation point, otherwise priming failed + * or another failure occurred */ + if(!iq->dp) { +@@ -2568,6 +2622,62 @@ processFinished(struct module_qstate* qs + return 0; + } + ++/** ++ * ASN: Do final processing on responses to A queries originated from AAAA ++ * queries. Events reach this state after the iterative resolution algorithm ++ * terminates. ++ * This is required down the road to decide whether to scrub AAAA records ++ * from the results or not. ++ * ++ * @param qstate: query state. ++ * @param id: module id. ++ * @param forq: super query state. ++ */ ++static void ++asn_processAAAAResponse(struct module_qstate* qstate, int id, ++ struct module_qstate* super) ++{ ++ struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; ++ struct iter_qstate* super_iq = (struct iter_qstate*)super->minfo[id]; ++ struct ub_packed_rrset_key* rrset; ++ struct delegpt_ns* dpns = NULL; ++ int error = (qstate->return_rcode != LDNS_RCODE_NOERROR); ++ ++ log_assert(super_iq->fetch_a_for_aaaa > 0); ++ ++ /* let super go to evaluation of targets after this */ ++ super_iq->state = QUERYTARGETS_STATE; ++ ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse", ++ &qstate->qinfo); ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: processAAAAResponse super", ++ &super->qinfo); ++ ++ if(super_iq->dp) ++ dpns = delegpt_find_ns(super_iq->dp, ++ qstate->qinfo.qname, qstate->qinfo.qname_len); ++ if (!dpns) { ++ /* not interested */ ++ verbose(VERB_ALGO, "ASN-AAAA-filter: subq: %s, but parent not " ++ "interested%s", (error ? "error, but" : "success"), ++ (super_iq->dp ? "anymore" : " (was reset)")); ++ log_query_info(VERB_ALGO, "ASN-AAAA-filter: superq", &super->qinfo); ++ if(super_iq->dp && error) ++ delegpt_log(VERB_ALGO, super_iq->dp); ++ return; ++ } else if (error) { ++ verbose(VERB_ALGO, "ASN-AAAA-filter: mark as failed, " ++ "and go to target query."); ++ /* see if the failure did get (parent-lame) info */ ++ if(!cache_fill_missing(super->env, ++ super_iq->qchase.qclass, super->region, ++ super_iq->dp)) ++ log_err("ASN-AAAA-filter: out of memory adding missing"); ++ dpns->resolved = 1; /* mark as failed */ ++ } ++} ++/* ASN: End of added code */ ++ + /* + * Return priming query results to interestes super querystates. + * +@@ -2587,6 +2697,9 @@ iter_inform_super(struct module_qstate* + else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*) + super->minfo[id])->state == DSNS_FIND_STATE) + processDSNSResponse(qstate, id, super); ++ else if (super->qinfo.qtype == LDNS_RR_TYPE_AAAA && ((struct iter_qstate*) ++ super->minfo[id])->state == ASN_FETCH_A_FOR_AAAA_STATE) ++ asn_processAAAAResponse(qstate, id, super); + else if(qstate->return_rcode != LDNS_RCODE_NOERROR) + error_supers(qstate, id, super); + else if(qstate->is_priming) +@@ -2624,6 +2737,9 @@ iter_handle(struct module_qstate* qstate + case INIT_REQUEST_3_STATE: + cont = processInitRequest3(qstate, iq, id); + break; ++ case ASN_FETCH_A_FOR_AAAA_STATE: ++ cont = asn_processQueryAAAA(qstate, iq, ie, id); ++ break; + case QUERYTARGETS_STATE: + cont = processQueryTargets(qstate, iq, ie, id); + break; +@@ -2863,6 +2979,8 @@ iter_state_to_string(enum iter_state sta + return "INIT REQUEST STATE (stage 2)"; + case INIT_REQUEST_3_STATE: + return "INIT REQUEST STATE (stage 3)"; ++ case ASN_FETCH_A_FOR_AAAA_STATE: ++ return "ASN_FETCH_A_FOR_AAAA_STATE"; + case QUERYTARGETS_STATE : + return "QUERY TARGETS STATE"; + case PRIME_RESP_STATE : +@@ -2887,6 +3005,7 @@ iter_state_is_responsestate(enum iter_st + case INIT_REQUEST_STATE : + case INIT_REQUEST_2_STATE : + case INIT_REQUEST_3_STATE : ++ case ASN_FETCH_A_FOR_AAAA_STATE : + case QUERYTARGETS_STATE : + case COLLECT_CLASS_STATE : + return 0; +--- unbound-1.4.17.orig/iterator/iter_utils.c ++++ unbound-1.4.17/iterator/iter_utils.c +@@ -128,6 +128,7 @@ iter_apply_cfg(struct iter_env* iter_env + } + iter_env->supports_ipv6 = cfg->do_ip6; + iter_env->supports_ipv4 = cfg->do_ip4; ++ iter_env->aaaa_filter = cfg->aaaa_filter; + return 1; + } + +--- unbound-1.4.17.orig/iterator/iterator.h ++++ unbound-1.4.17/iterator/iterator.h +@@ -110,6 +110,9 @@ struct iter_env { + * array of max_dependency_depth+1 size. + */ + int* target_fetch_policy; ++ ++ /** ASN: AAAA-filter flag */ ++ int aaaa_filter; + }; + + /** +@@ -135,6 +138,14 @@ enum iter_state { + INIT_REQUEST_3_STATE, + + /** ++ * This state is responsible for intercepting AAAA queries, ++ * and launch a A subquery on the same target, to populate the ++ * cache with A records, so the AAAA filter scrubbing logic can ++ * work. ++ */ ++ ASN_FETCH_A_FOR_AAAA_STATE, ++ ++ /** + * Each time a delegation point changes for a given query or a + * query times out and/or wakes up, this state is (re)visited. + * This state is reponsible for iterating through a list of +@@ -309,6 +320,13 @@ struct iter_qstate { + */ + int refetch_glue; + ++ /** ++ * ASN: This is a flag that, if true, means that this query is ++ * for fetching A records to populate cache and determine if we must ++ * return AAAA records or not. ++ */ ++ int fetch_a_for_aaaa; ++ + /** list of pending queries to authoritative servers. */ + struct outbound_list outlist; + }; +--- unbound-1.4.17.orig/util/config_file.h ++++ unbound-1.4.17/util/config_file.h +@@ -169,6 +169,8 @@ struct config_file { + int harden_referral_path; + /** use 0x20 bits in query as random ID bits */ + int use_caps_bits_for_id; ++ /** ASN: enable AAAA filter? */ ++ int aaaa_filter; + /** strip away these private addrs from answers, no DNS Rebinding */ + struct config_strlist* private_address; + /** allow domain (and subdomains) to use private address space */ +--- unbound-1.4.17.orig/util/configlexer.lex ++++ unbound-1.4.17/util/configlexer.lex +@@ -177,6 +177,7 @@ harden-below-nxdomain{COLON} { YDVAR(1, + harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } + use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) } + unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } ++aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) } + private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } + private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } + prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } +--- unbound-1.4.17.orig/util/configparser.y ++++ unbound-1.4.17/util/configparser.y +@@ -92,6 +92,7 @@ extern struct config_parser_state* cfg_p + %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT + %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR + %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS ++%token VAR_AAAA_FILTER + %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE + %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE + %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE +@@ -151,6 +152,7 @@ content_server: server_num_threads | ser + server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | + server_harden_referral_path | server_private_address | + server_private_domain | server_extended_statistics | ++ server_aaaa_filter | + server_local_data_ptr | server_jostle_timeout | + server_unwanted_reply_threshold | server_log_time_ascii | + server_domain_insecure | server_val_sig_skew_min | +@@ -802,6 +803,15 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR + free($2); + } + ; ++server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG ++ { ++ OUTYY(("P(server_aaaa_filter:%s)\n", $2)); ++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) ++ yyerror("expected yes or no."); ++ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0); ++ free($2); ++ } ++ ; + server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG + { + OUTYY(("P(server_private_address:%s)\n", $2)); +--- unbound-1.4.17.orig/pythonmod/interface.i ++++ unbound-1.4.17/pythonmod/interface.i +@@ -626,6 +626,7 @@ struct config_file { + int harden_dnssec_stripped; + int harden_referral_path; + int use_caps_bits_for_id; ++ int aaaa_filter; /* ASN */ + struct config_strlist* private_address; + struct config_strlist* private_domain; + size_t unwanted_threshold; diff --git a/daemon/cachedump.c b/daemon/cachedump.c index cf5b1a12c9a..20a46ae4dff 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -664,7 +664,7 @@ load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker) if(!go_on) return 1; /* skip this one, not all references satisfied */ - if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) { + if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags)) { log_warn("error out of memory"); return 0; } diff --git a/daemon/remote.c b/daemon/remote.c index 88ea063f21f..ff3d769d4e5 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -854,7 +854,8 @@ print_ext(SSL* ssl, struct stats_info* s) /* RCODE */ for(i=0; isvr.ans_rcode[i] == 0) + /* Always include RCODEs 0-5 */ + if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0) continue; lt = sldns_lookup_by_id(sldns_rcodes, i); if(lt && lt->name) { @@ -1094,8 +1095,13 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen, k.qname_len = nmlen; k.qtype = t; k.qclass = c; - h = query_info_hash(&k); + h = query_info_hash(&k, 0); slabhash_remove(worker->env.msg_cache, h, &k); + if(t == LDNS_RR_TYPE_AAAA) { + /* for AAAA also flush dns64 bit_cd packet */ + h = query_info_hash(&k, BIT_CD); + slabhash_remove(worker->env.msg_cache, h, &k); + } } /** flush a type */ diff --git a/daemon/unbound.c b/daemon/unbound.c index a53fe954db2..5ded5a964cc 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -287,7 +287,7 @@ checkrlimits(struct config_file* cfg) #ifdef HAVE_SETRLIMIT } #endif - log_warn("increased limit(open files) from %u to %u", + verbose(VERB_ALGO, "increased limit(open files) from %u to %u", (unsigned)avail, (unsigned)total+10); } #else diff --git a/daemon/worker.c b/daemon/worker.c index f9067621385..59ae9dfcefc 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -935,7 +935,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, &repinfo->addr, repinfo->addrlen); goto send_reply; } - h = query_info_hash(&qinfo); + h = query_info_hash(&qinfo, sldns_buffer_read_u16_at(c->buffer, 2)); if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) { /* answer from cache - we have acquired a readlock on it */ if(answer_from_cache(worker, &qinfo, diff --git a/dns64/dns64.c b/dns64/dns64.c index 963e727fed7..eaaa26f7c91 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -399,7 +399,7 @@ handle_ipv6_ptr(struct module_qstate* qstate, int id) /* Create the new sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, + if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0, &subq)) return module_error; if (subq) { @@ -451,7 +451,7 @@ generate_type_A_query(struct module_qstate* qstate, int id) /* Start the sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, - &subq)) + 0, &subq)) { verbose(VERB_ALGO, "dns64: sub-query creation failed"); return module_error; @@ -520,11 +520,13 @@ handle_event_moddone(struct module_qstate* qstate, int id) * * - An internal query. * - A query for a record type other than AAAA. + * - CD FLAG was set on querier * - An AAAA query for which an error was returned. * - A successful AAAA query with an answer. */ if ( (enum dns64_qstate)qstate->minfo[id] == DNS64_INTERNAL_QUERY || qstate->qinfo.qtype != LDNS_RR_TYPE_AAAA + || (qstate->query_flags & BIT_CD) || qstate->return_rcode != LDNS_RCODE_NOERROR || (qstate->return_msg && qstate->return_msg->rep && @@ -813,7 +815,7 @@ dns64_inform_super(struct module_qstate* qstate, int id, /* Store the generated response in cache. */ if (!dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, - 0, 0, 0, NULL)) + 0, 0, 0, NULL, super->query_flags)) log_err("out of memory"); } diff --git a/doc/Changelog b/doc/Changelog index bd6f5456bb1..192b87c8412 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,9 +1,69 @@ +8 December 2014: Wouter + - Fix CVE-2014-8602: denial of service by making resolver chase + endless series of delegations. + +1 December 2014: Wouter + - Fix bug#632: unbound fails to build on AArch64, protects + getentropy compat code from calling sysctl if it is has been removed. + +29 November 2014: Wouter + - Add include to getentropy_linux.c, hopefully fixing debian build. + +28 November 2014: Wouter + - Fix makefile for build from noexec source tree. + +26 November 2014: Wouter + - Fix libunbound undefined symbol errors for main. + Referencing main does not seem to be possible for libunbound. + +24 November 2014: Wouter + - Fix log at high verbosity and memory allocation failure. + - iana portlist update. + +21 November 2014: Wouter + - Fix crash on multiple thread random usage on systems without + arc4random. + +20 November 2014: Wouter + - fix compat/getentropy_win.c check if CryptGenRandom works and no + immediate exit on windows. + +19 November 2014: Wouter + - Fix cdflag dns64 processing. + +18 November 2014: Wouter + - Fix that CD flag disables DNS64 processing, returning the DNSSEC + signed AAAA denial. + - iana portlist update. + +17 November 2014: Wouter + - Fix #627: SSL_CTX_load_verify_locations return code not properly + checked. + +14 November 2014: Wouter + - parser with bison 2.7 + +13 November 2014: Wouter + - Patch from Stephane Lapie for ASAHI Net that implements aaaa-filter, + added to contrib/aaaa-filter-iterator.patch. + +12 November 2014: Wouter + - trunk has 1.5.1 in development. + - Patch from Robert Edmonds to build pyunbound python module + differently. No versioninfo, with -shared and without $(LIBS). + - Patch from Robert Edmonds fixes hyphens in unbound-anchor man page. + - Removed 'increased limit open files' log message that is written + to console. It is only written on verbosity 4 and higher. + This keeps system bootup console cleaner. + - Patch from James Raftery, always print stats for rcodes 0..5. + 11 November 2014: Wouter - iana portlist update. - Fix bug where forward or stub addresses with same address but different port number were not tried. - version number in svn trunk is 1.5.0 - tag 1.5.0rc1 + - review fix from Ralph. 7 November 2014: Wouter - dnstap fixes by Robert Edmonds: diff --git a/doc/README b/doc/README index d194aa0058a..df92fccb5d3 100644 --- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -README for Unbound 1.5.0 +README for Unbound 1.5.1 Copyright 2007 NLnet Labs http://unbound.net diff --git a/doc/example.conf.in b/doc/example.conf.in index 294be92d51a..b95b3a6339c 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -1,7 +1,7 @@ # # Example configuration file. # -# See unbound.conf(5) man page, version 1.5.0. +# See unbound.conf(5) man page, version 1.5.1. # # this is a comment. diff --git a/doc/libunbound.3.in b/doc/libunbound.3.in index 98abd28e2d4..55a9cb286e6 100644 --- a/doc/libunbound.3.in +++ b/doc/libunbound.3.in @@ -1,4 +1,4 @@ -.TH "libunbound" "3" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "libunbound" "3" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" libunbound.3 -- unbound library functions manual .\" @@ -42,7 +42,7 @@ .B ub_ctx_zone_remove, .B ub_ctx_data_add, .B ub_ctx_data_remove -\- Unbound DNS validating resolver 1.5.0 functions. +\- Unbound DNS validating resolver 1.5.1 functions. .SH "SYNOPSIS" .B #include .LP diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in index 6036dd241f6..80a3438dcaa 100644 --- a/doc/unbound-anchor.8.in +++ b/doc/unbound-anchor.8.in @@ -1,4 +1,4 @@ -.TH "unbound-anchor" "8" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound-anchor" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" @@ -24,14 +24,14 @@ Suggested usage: .nf # in the init scripts. # provide or update the root anchor (if necessary) - unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@" + unbound-anchor \-a "@UNBOUND_ROOTKEY_FILE@" # Please note usage of this root anchor is at your own risk # and under the terms of our LICENSE (see source). # # start validating resolver # the unbound.conf contains: # auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" - unbound -c unbound.conf + unbound \-c unbound.conf .fi .P This tool provides builtin default contents for the root anchor and root @@ -138,7 +138,7 @@ tracking, or if an error occurred. .P You can check the exit value in this manner: .nf - unbound-anchor -a "root.key" || logger "Please check root.key" + unbound-anchor \-a "root.key" || logger "Please check root.key" .fi Or something more suitable for your operational environment. .SH "TRUST" diff --git a/doc/unbound-checkconf.8.in b/doc/unbound-checkconf.8.in index 6253729ccb2..5ab53480b6f 100644 --- a/doc/unbound-checkconf.8.in +++ b/doc/unbound-checkconf.8.in @@ -1,4 +1,4 @@ -.TH "unbound-checkconf" "8" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound-checkconf" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound-checkconf.8 -- unbound configuration checker manual .\" diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index bfe24c2ed1c..92d2d1a9343 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -1,4 +1,4 @@ -.TH "unbound-control" "8" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound-control" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound-control.8 -- unbound remote control manual .\" diff --git a/doc/unbound-host.1.in b/doc/unbound-host.1.in index c2b047b3c0c..d9e92bbe099 100644 --- a/doc/unbound-host.1.in +++ b/doc/unbound-host.1.in @@ -1,4 +1,4 @@ -.TH "unbound\-host" "1" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound\-host" "1" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound-host.1 -- unbound DNS lookup utility .\" diff --git a/doc/unbound.8.in b/doc/unbound.8.in index 27e54d6e515..3b74a3242ad 100644 --- a/doc/unbound.8.in +++ b/doc/unbound.8.in @@ -1,4 +1,4 @@ -.TH "unbound" "8" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound" "8" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound.8 -- unbound manual .\" @@ -9,7 +9,7 @@ .\" .SH "NAME" .B unbound -\- Unbound DNS validating resolver 1.5.0. +\- Unbound DNS validating resolver 1.5.1. .SH "SYNOPSIS" .B unbound .RB [ \-h ] diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index cd0af718fb9..f08a01b3184 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1,4 +1,4 @@ -.TH "unbound.conf" "5" "Nov 18, 2014" "NLnet Labs" "unbound 1.5.0" +.TH "unbound.conf" "5" "Dec 8, 2014" "NLnet Labs" "unbound 1.5.1" .\" .\" unbound.conf.5 -- unbound.conf manual .\" diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 4148c1268f7..9d0aa698f99 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -425,10 +425,10 @@ dns_copy_msg(struct dns_msg* from, struct regional* region) void iter_dns_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region) + struct regional* region, uint16_t flags) { if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway, - pside, region)) + pside, region, flags)) log_err("out of memory: cannot store data in cache"); } @@ -457,7 +457,8 @@ causes_cycle(struct module_qstate* qstate, uint8_t* name, size_t namelen, fptr_ok(fptr_whitelist_modenv_detect_cycle( qstate->env->detect_cycle)); return (*qstate->env->detect_cycle)(qstate, &qinf, - (uint16_t)(BIT_RD|BIT_CD), qstate->is_priming); + (uint16_t)(BIT_RD|BIT_CD), qstate->is_priming, + qstate->is_valrec); } void diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index abdc68f3cd4..d7c2b68afa2 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -124,6 +124,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); * @param pside: true if dp is parentside, thus message is 'fresh' and NS * can be prefetch-updates. * @param region: to copy modified (cache is better) rrs back to. + * @param flags: with BIT_CD for dns64 AAAA translated queries. * @return void, because we are not interested in alloc errors, * the iterator and validator can operate on the results in their * scratch space (the qstate.region) and are not dependent on the cache. @@ -132,7 +133,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); */ void iter_dns_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region); + struct regional* region, uint16_t flags); /** * Select randomly with n/m probability. diff --git a/iterator/iterator.c b/iterator/iterator.c index df5f645cc28..6e05c99a0e9 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -120,6 +120,7 @@ iter_new(struct module_qstate* qstate, int id) iq->query_restart_count = 0; iq->referral_count = 0; iq->sent_count = 0; + iq->target_count = NULL; iq->wait_priming_stub = 0; iq->refetch_glue = 0; iq->dnssec_expected = 0; @@ -257,7 +258,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) verbose(VERB_ALGO, "error response for prefetch in cache"); /* attempt to adjust the cache entry prefetch */ if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo, - NORR_TTL)) + NORR_TTL, qstate->query_flags)) return error_response(qstate, id, rcode); /* if that fails (not in cache), fall through to store err */ } @@ -270,7 +271,8 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) /* do not waste time trying to validate this servfail */ err.security = sec_status_indeterminate; verbose(VERB_ALGO, "store error response in message cache"); - iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL); + iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, + qstate->query_flags); return error_response(qstate, id, rcode); } @@ -453,6 +455,26 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq, return 1; } +/** create target count structure for this query */ +static void +target_count_create(struct iter_qstate* iq) +{ + if(!iq->target_count) { + iq->target_count = (int*)calloc(2, sizeof(int)); + /* if calloc fails we simply do not track this number */ + if(iq->target_count) + iq->target_count[0] = 1; + } +} + +static void +target_count_increase(struct iter_qstate* iq, int num) +{ + target_count_create(iq); + if(iq->target_count) + iq->target_count[1] += num; +} + /** * Generate a subrequest. * Generate a local request event. Local events are tied to this module, and @@ -486,6 +508,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qflags = 0; /* OPCODE QUERY, no flags */ struct query_info qinf; int prime = (finalstate == PRIME_RESP_STATE)?1:0; + int valrec = 0; qinf.qname = qname; qinf.qname_len = qnamelen; qinf.qtype = qtype; @@ -499,12 +522,15 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, * the resolution chain, which might have a validator. We are * uninterested in validating things not on the direct resolution * path. */ - if(!v) + if(!v) { qflags |= BIT_CD; + valrec = 1; + } /* attach subquery, lookup existing or make a new one */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) { + if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, + &subq)) { return 0; } *subq_ret = subq; @@ -524,6 +550,10 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype, subiq = (struct iter_qstate*)subq->minfo[id]; memset(subiq, 0, sizeof(*subiq)); subiq->num_target_queries = 0; + target_count_create(iq); + subiq->target_count = iq->target_count; + if(iq->target_count) + iq->target_count[0] ++; /* extra reference */ subiq->num_current_queries = 0; subiq->depth = iq->depth+1; outbound_list_init(&subiq->outlist); @@ -938,7 +968,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, } else { msg = dns_cache_lookup(qstate->env, iq->qchase.qname, iq->qchase.qname_len, iq->qchase.qtype, - iq->qchase.qclass, qstate->region, qstate->env->scratch); + iq->qchase.qclass, qstate->query_flags, + qstate->region, qstate->env->scratch); if(!msg && qstate->env->neg_cache) { /* lookup in negative cache; may result in * NOERROR/NODATA or NXDOMAIN answers that need validation */ @@ -1350,6 +1381,12 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, if(iq->depth == ie->max_dependency_depth) return 0; + if(iq->depth > 0 && iq->target_count && + iq->target_count[1] > MAX_TARGET_COUNT) { + verbose(VERB_QUERY, "request has exceeded the maximum " + "number of glue fetches %d", iq->target_count[1]); + return 0; + } iter_mark_cycle_targets(qstate, iq->dp); missing = (int)delegpt_count_missing_targets(iq->dp); @@ -1532,6 +1569,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += qs; + target_count_increase(iq, qs); if(qs != 0) { qstate->ext_state[id] = module_wait_subquery; return 0; /* and wait for them */ @@ -1541,6 +1579,12 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, verbose(VERB_QUERY, "maxdepth and need more nameservers, fail"); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } + if(iq->depth > 0 && iq->target_count && + iq->target_count[1] > MAX_TARGET_COUNT) { + verbose(VERB_QUERY, "request has exceeded the maximum " + "number of glue fetches %d", iq->target_count[1]); + return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); + } /* mark cycle targets for parent-side lookups */ iter_mark_pside_cycle_targets(qstate, iq->dp); /* see if we can issue queries to get nameserver addresses */ @@ -1570,6 +1614,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, if(query_count != 0) { /* suspend to await results */ verbose(VERB_ALGO, "try parent-side glue lookup"); iq->num_target_queries += query_count; + target_count_increase(iq, query_count); qstate->ext_state[id] = module_wait_subquery; return 0; } @@ -1725,6 +1770,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return error_response(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += extra; + target_count_increase(iq, extra); if(iq->num_target_queries > 0) { /* wait to get all targets, we want to try em */ verbose(VERB_ALGO, "wait for all targets for fallback"); @@ -1765,6 +1811,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, /* errors ignored, these targets are not strictly necessary for * this result, we do not have to reply with SERVFAIL */ iq->num_target_queries += extra; + target_count_increase(iq, extra); } /* Add the current set of unused targets to our queue. */ @@ -1810,6 +1857,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, return 1; } iq->num_target_queries += qs; + target_count_increase(iq, qs); } /* Since a target query might have been made, we * need to check again. */ @@ -1991,7 +2039,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 0, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, - qstate->region); + qstate->region, qstate->query_flags); /* close down outstanding requests to be discarded */ outbound_list_clear(&iq->outlist); iq->num_current_queries = 0; @@ -2029,7 +2077,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, /* Store the referral under the current query */ /* no prefetch-leeway, since its not the answer */ iter_dns_store(qstate->env, &iq->response->qinfo, - iq->response->rep, 1, 0, 0, NULL); + iq->response->rep, 1, 0, 0, NULL, 0); if(iq->store_parent_NS) iter_store_parentside_NS(qstate->env, iq->response->rep); @@ -2128,7 +2176,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, /* prefetchleeway applied because this updates answer parts */ iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 1, qstate->prefetch_leeway, - iq->dp&&iq->dp->has_parent_side_NS, NULL); + iq->dp&&iq->dp->has_parent_side_NS, NULL, + qstate->query_flags); /* set the current request's qname to the new value. */ iq->qchase.qname = sname; iq->qchase.qname_len = snamelen; @@ -2209,7 +2258,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, } /** - * Return priming query results to interestes super querystates. + * Return priming query results to interested super querystates. * * Sets the delegation point and delegation message (not nonRD queries). * This is a callback from walk_supers. @@ -2640,7 +2689,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, iter_dns_store(qstate->env, &qstate->qinfo, iq->response->rep, 0, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, - qstate->region); + qstate->region, qstate->query_flags); } } qstate->return_rcode = LDNS_RCODE_NOERROR; @@ -2921,6 +2970,8 @@ iter_clear(struct module_qstate* qstate, int id) iq = (struct iter_qstate*)qstate->minfo[id]; if(iq) { outbound_list_clear(&iq->outlist); + if(iq->target_count && --iq->target_count[0] == 0) + free(iq->target_count); iq->num_current_queries = 0; } qstate->minfo[id] = NULL; diff --git a/iterator/iterator.h b/iterator/iterator.h index 0b91760d4a4..1364b86d722 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -52,6 +52,8 @@ struct iter_donotq; struct iter_prep_list; struct iter_priv; +/** max number of targets spawned for a query and its subqueries */ +#define MAX_TARGET_COUNT 32 /** max number of query restarts. Determines max number of CNAME chain. */ #define MAX_RESTART_COUNT 8 /** max number of referrals. Makes sure resolver does not run away */ @@ -251,6 +253,10 @@ struct iter_qstate { /** number of queries fired off */ int sent_count; + + /** number of target queries spawned in [1], for this query and its + * subqueries, the malloced-array is shared, [0] refcount. */ + int* target_count; /** * The query must store NS records from referrals as parentside RRs diff --git a/libunbound/unbound.h b/libunbound/unbound.h index 567f48271e3..fe903d0c51d 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -357,7 +357,7 @@ int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta); int ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname); /** - * Add trust anchor to the give context that is tracked with RFC5011 + * Add trust anchor to the given context that is tracked with RFC5011 * automated trust anchor maintenance. The file is written to when the * trust anchor is changed. * Pass the name of a file that was output from eg. unbound-anchor, diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c index 2f3848008e2..1091dcf1072 100644 --- a/pythonmod/pythonmod_utils.c +++ b/pythonmod/pythonmod_utils.c @@ -67,7 +67,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, st } return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, - qstate->prefetch_leeway, 0, NULL); + qstate->prefetch_leeway, 0, NULL, qstate->query_flags); } /* Invalidate the message associated with query_info stored in message cache */ @@ -78,7 +78,7 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin struct reply_info *r; size_t i, j; - h = query_info_hash(qinfo); + h = query_info_hash(qinfo, qstate->query_flags); if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0))) { r = (struct reply_info*)(e->data); diff --git a/services/cache/dns.c b/services/cache/dns.c index c663b8e8b9a..4692744a15d 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -184,7 +184,7 @@ addr_to_additional(struct ub_packed_rrset_key* rrset, struct regional* region, /** lookup message in message cache */ static struct msgreply_entry* msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, - uint16_t qtype, uint16_t qclass, time_t now, int wr) + uint16_t qtype, uint16_t qclass, uint16_t flags, time_t now, int wr) { struct lruhash_entry* e; struct query_info k; @@ -194,7 +194,7 @@ msg_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, k.qname_len = qnamelen; k.qtype = qtype; k.qclass = qclass; - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, wr); if(!e) return NULL; @@ -226,8 +226,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass, addr_to_additional(akey, region, *msg, now); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_A, qclass, now, 0); + LDNS_RR_TYPE_A, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -244,8 +246,10 @@ find_add_addrs(struct module_env* env, uint16_t qclass, addr_to_additional(akey, region, *msg, now); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_AAAA, qclass, now, 0); + LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -276,8 +280,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, ns->name, LDNS_RR_TYPE_A, qclass); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_A, qclass, now, 0); + LDNS_RR_TYPE_A, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -294,8 +300,10 @@ cache_fill_missing(struct module_env* env, uint16_t qclass, ns->name, LDNS_RR_TYPE_AAAA, qclass); lock_rw_unlock(&akey->entry.lock); } else { + /* BIT_CD on false because delegpt lookup does + * not use dns64 translation */ neg = msg_cache_lookup(env, ns->name, ns->namelen, - LDNS_RR_TYPE_AAAA, qclass, now, 0); + LDNS_RR_TYPE_AAAA, qclass, 0, now, 0); if(neg) { delegpt_add_neg_msg(dp, neg); lock_rw_unlock(&neg->entry.lock); @@ -626,7 +634,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region, struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - struct regional* region, struct regional* scratch) + uint16_t flags, struct regional* region, struct regional* scratch) { struct lruhash_entry* e; struct query_info k; @@ -639,7 +647,7 @@ dns_cache_lookup(struct module_env* env, k.qname_len = qnamelen; k.qtype = qtype; k.qclass = qclass; - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, 0); if(e) { struct msgreply_entry* key = (struct msgreply_entry*)e->key; @@ -716,7 +724,7 @@ dns_cache_lookup(struct module_env* env, if(env->cfg->harden_below_nxdomain) while(!dname_is_root(k.qname)) { dname_remove_label(&k.qname, &k.qname_len); - h = query_info_hash(&k); + h = query_info_hash(&k, flags); e = slabhash_lookup(env->msg_cache, h, &k, 0); if(e) { struct reply_info* data = (struct reply_info*)e->data; @@ -741,7 +749,7 @@ dns_cache_lookup(struct module_env* env, int dns_cache_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region) + struct regional* region, uint16_t flags) { struct reply_info* rep = NULL; /* alloc, malloc properly (not in region, like msg is) */ @@ -786,7 +794,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, * Not AA from cache. Not CD in cache (depends on client bit). */ rep->flags |= (BIT_RA | BIT_QR); rep->flags &= ~(BIT_AA | BIT_CD); - h = query_info_hash(&qinf); + h = query_info_hash(&qinf, flags); dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep, region); /* qname is used inside query_info_entrysetup, and set to @@ -798,11 +806,11 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, - time_t adjust) + time_t adjust, uint16_t flags) { struct msgreply_entry* msg; msg = msg_cache_lookup(env, qinfo->qname, qinfo->qname_len, - qinfo->qtype, qinfo->qclass, *env->now, 1); + qinfo->qtype, qinfo->qclass, flags, *env->now, 1); if(msg) { struct reply_info* rep = (struct reply_info*)msg->entry.data; if(rep) { diff --git a/services/cache/dns.h b/services/cache/dns.h index 05a3e629654..69796c2eb20 100644 --- a/services/cache/dns.h +++ b/services/cache/dns.h @@ -79,11 +79,12 @@ struct dns_msg { * can be updated to full TTL even in prefetch situations. * @param region: region to allocate better entries from cache into. * (used when is_referral is false). + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @return 0 on alloc error (out of memory). */ int dns_cache_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region); + struct regional* region, uint16_t flags); /** * Store message in the cache. Stores in message cache and rrset cache. @@ -132,6 +133,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env, * @param qnamelen: length of qname. * @param qtype: query type. * @param qclass: query class. + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @param region: where to allocate result. * @param scratch: where to allocate temporary data. * @return new response message (alloced in region, rrsets do not have IDs). @@ -140,7 +142,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env, */ struct dns_msg* dns_cache_lookup(struct module_env* env, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - struct regional* region, struct regional* scratch); + uint16_t flags, struct regional* region, struct regional* scratch); /** * find and add A and AAAA records for missing nameservers in delegpt @@ -186,9 +188,10 @@ int dns_msg_authadd(struct dns_msg* msg, struct regional* region, * @param env: module environment with caches and time. * @param qinfo: query info for the query that needs adjustment. * @param adjust: time in seconds to add to the prefetch_leeway. + * @param flags: flags with BIT_CD for AAAA queries in dns64 translation. * @return false if not in cache. true if added. */ int dns_cache_prefetch_adjust(struct module_env* env, struct query_info* qinfo, - time_t adjust); + time_t adjust, uint16_t flags); #endif /* SERVICES_CACHE_DNS_H */ diff --git a/services/mesh.c b/services/mesh.c index bc711d9b3ed..a69aced223e 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -132,6 +132,11 @@ mesh_state_compare(const void* ap, const void* bp) if(!a->s.is_priming && b->s.is_priming) return 1; + if(a->s.is_valrec && !b->s.is_valrec) + return -1; + if(!a->s.is_valrec && b->s.is_valrec) + return 1; + if((a->s.query_flags&BIT_RD) && !(b->s.query_flags&BIT_RD)) return -1; if(!(a->s.query_flags&BIT_RD) && (b->s.query_flags&BIT_RD)) @@ -277,11 +282,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, struct comm_reply* rep, uint16_t qid) { - /* do not use CD flag from user for mesh state, we want the CD-query - * to receive validation anyway, to protect out cache contents and - * avoid bad-data in this cache that a downstream validator cannot - * remove from this cache */ - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); int was_detached = 0; int was_noreply = 0; int added = 0; @@ -311,7 +312,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { log_err("mesh_state_create: out of memory; SERVFAIL"); error_encode(rep->c->buffer, LDNS_RCODE_SERVFAIL, @@ -375,7 +376,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, sldns_buffer* buf, uint16_t qid, mesh_cb_func_t cb, void* cb_arg) { - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); int was_detached = 0; int was_noreply = 0; int added = 0; @@ -386,7 +387,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { return 0; } @@ -428,7 +429,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, time_t leeway) { - struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&BIT_RD, 0); + struct mesh_state* s = mesh_area_find(mesh, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); #ifdef UNBOUND_DEBUG struct rbnode_t* n; #endif @@ -447,7 +448,7 @@ void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo, mesh->stats_dropped ++; return; } - s = mesh_state_create(mesh->env, qinfo, qflags&BIT_RD, 0); + s = mesh_state_create(mesh->env, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); if(!s) { log_err("prefetch mesh_state_create: out of memory"); return; @@ -496,7 +497,7 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e, struct mesh_state* mesh_state_create(struct module_env* env, struct query_info* qinfo, - uint16_t qflags, int prime) + uint16_t qflags, int prime, int valrec) { struct regional* region = alloc_reg_obtain(env->alloc); struct mesh_state* mstate; @@ -533,6 +534,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo, /* remove all weird bits from qflags */ mstate->s.query_flags = (qflags & (BIT_RD|BIT_CD)); mstate->s.is_priming = prime; + mstate->s.is_valrec = valrec; mstate->s.reply = NULL; mstate->s.region = region; mstate->s.curmod = 0; @@ -679,11 +681,12 @@ void mesh_detach_subs(struct module_qstate* qstate) } int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq) + uint16_t qflags, int prime, int valrec, struct module_qstate** newq) { /* find it, if not, create it */ struct mesh_area* mesh = qstate->env->mesh; - struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime); + struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime, + valrec); int was_detached; if(mesh_detect_cycle_found(qstate, sub)) { verbose(VERB_ALGO, "attach failed, cycle detected"); @@ -694,7 +697,8 @@ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, struct rbnode_t* n; #endif /* create a new one */ - sub = mesh_state_create(qstate->env, qinfo, qflags, prime); + sub = mesh_state_create(qstate->env, qinfo, qflags, prime, + valrec); if(!sub) { log_err("mesh_attach_sub: out of memory"); return 0; @@ -941,13 +945,14 @@ void mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate) } struct mesh_state* mesh_area_find(struct mesh_area* mesh, - struct query_info* qinfo, uint16_t qflags, int prime) + struct query_info* qinfo, uint16_t qflags, int prime, int valrec) { struct mesh_state key; struct mesh_state* result; key.node.key = &key; key.s.is_priming = prime; + key.s.is_valrec = valrec; key.s.qinfo = *qinfo; key.s.query_flags = qflags; @@ -1107,8 +1112,9 @@ mesh_log_list(struct mesh_area* mesh) struct mesh_state* m; int num = 0; RBTREE_FOR(m, struct mesh_state*, &mesh->all) { - snprintf(buf, sizeof(buf), "%d%s%s%s%s%s mod%d %s%s", + snprintf(buf, sizeof(buf), "%d%s%s%s%s%s%s mod%d %s%s", num++, (m->s.is_priming)?"p":"", /* prime */ + (m->s.is_valrec)?"v":"", /* prime */ (m->s.query_flags&BIT_RD)?"RD":"", (m->s.query_flags&BIT_CD)?"CD":"", (m->super_set.count==0)?"d":"", /* detached */ @@ -1178,10 +1184,11 @@ mesh_get_mem(struct mesh_area* mesh) int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime) + uint16_t flags, int prime, int valrec) { struct mesh_area* mesh = qstate->env->mesh; - struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime); + struct mesh_state* dep_m = mesh_area_find(mesh, qinfo, flags, prime, + valrec); return mesh_detect_cycle_found(qstate, dep_m); } diff --git a/services/mesh.h b/services/mesh.h index fbfbbcb4a94..086e39094e8 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -353,12 +353,13 @@ void mesh_detach_subs(struct module_qstate* qstate); * @param qinfo: what to query for (copied). * @param qflags: what flags to use (RD / CD flag or not). * @param prime: if it is a (stub) priming query. + * @param valrec: if it is a validation recursion query (lookup of key, DS). * @param newq: If the new subquery needs initialisation, it is returned, * otherwise NULL is returned. * @return: false on error, true if success (and init may be needed). */ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq); + uint16_t qflags, int prime, int valrec, struct module_qstate** newq); /** * Query state is done, send messages to reply entries. @@ -406,10 +407,12 @@ void mesh_state_delete(struct module_qstate* qstate); * @param qinfo: query info that the mesh is for. * @param qflags: flags for query (RD / CD flag). * @param prime: if true, it is a priming query, set is_priming on mesh state. + * @param valrec: if true, it is a validation recursion query, and sets + * is_valrec on the mesh state. * @return: new mesh state or NULL on allocation error. */ struct mesh_state* mesh_state_create(struct module_env* env, - struct query_info* qinfo, uint16_t qflags, int prime); + struct query_info* qinfo, uint16_t qflags, int prime, int valrec); /** * Cleanup a mesh state and its query state. Does not do rbtree or @@ -432,10 +435,11 @@ void mesh_delete_all(struct mesh_area* mesh); * @param qinfo: what query * @param qflags: if RD / CD bit is set or not. * @param prime: if it is a priming query. + * @param valrec: if it is a validation-recursion query. * @return: mesh state or NULL if not found. */ struct mesh_state* mesh_area_find(struct mesh_area* mesh, - struct query_info* qinfo, uint16_t qflags, int prime); + struct query_info* qinfo, uint16_t qflags, int prime, int valrec); /** * Setup attachment super/sub relation between super and sub mesh state. @@ -523,13 +527,14 @@ size_t mesh_get_mem(struct mesh_area* mesh); * @param qinfo: query info for dependency. * @param flags: query flags of dependency. * @param prime: if dependency is a priming query or not. + * @param valrec: if it is a validation recursion query (lookup of key, DS). * @return true if the name,type,class exists and the given qstate mesh exists * as a dependency of that name. Thus if qstate becomes dependent on * name,type,class then a cycle is created, this is return value 1. * Too large to search is value 2 (also true). */ int mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime); + uint16_t flags, int prime, int valrec); /** compare two mesh_states */ int mesh_state_compare(const void* ap, const void* bp); diff --git a/smallapp/unbound-host.c b/smallapp/unbound-host.c index 8020ad8c802..95973410924 100644 --- a/smallapp/unbound-host.c +++ b/smallapp/unbound-host.c @@ -409,7 +409,7 @@ extern int optind; /** getopt global, in case header files fail to declare it. */ extern char* optarg; -/** Main routine for checkconf */ +/** Main routine for unbound-host */ int main(int argc, char* argv[]) { int c; diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 126e7bef45b..68bcfd09ee3 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -576,10 +576,12 @@ reply_info_delete(void* d, void* ATTR_UNUSED(arg)) } hashvalue_t -query_info_hash(struct query_info *q) +query_info_hash(struct query_info *q, uint16_t flags) { hashvalue_t h = 0xab; h = hashlittle(&q->qtype, sizeof(q->qtype), h); + if(q->qtype == LDNS_RR_TYPE_AAAA && (flags&BIT_CD)) + h++; h = hashlittle(&q->qclass, sizeof(q->qclass), h); h = dname_query_hash(q->qname, h); return h; @@ -771,15 +773,14 @@ log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep) region, 65535, 1)) { log_info("%s: log_dns_msg: out of memory", str); } else { - char* str = sldns_wire2str_pkt(sldns_buffer_begin(buf), + char* s = sldns_wire2str_pkt(sldns_buffer_begin(buf), sldns_buffer_limit(buf)); - if(!str) { + if(!s) { log_info("%s: log_dns_msg: ldns tostr failed", str); } else { - log_info("%s %s", - str, (char*)sldns_buffer_begin(buf)); + log_info("%s %s", str, s); } - free(str); + free(s); } sldns_buffer_free(buf); regional_destroy(region); diff --git a/util/data/msgreply.h b/util/data/msgreply.h index ccbd0d74838..e8d6d762e01 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -305,8 +305,9 @@ void query_entry_delete(void *q, void* arg); /** delete reply_info data structure */ void reply_info_delete(void* d, void* arg); -/** calculate hash value of query_info, lowercases the qname */ -hashvalue_t query_info_hash(struct query_info *q); +/** calculate hash value of query_info, lowercases the qname, + * uses CD flag for AAAA qtype */ +hashvalue_t query_info_hash(struct query_info *q, uint16_t flags); /** * Setup query info entry diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index 3a5fc5f0611..5a77432c775 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -280,7 +280,7 @@ fptr_whitelist_modenv_detach_subs(void (*fptr)( int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq)) + uint16_t qflags, int prime, int valrec, struct module_qstate** newq)) { if(fptr == &mesh_attach_sub) return 1; return 0; @@ -296,7 +296,7 @@ fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)) int fptr_whitelist_modenv_detect_cycle(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime)) + uint16_t flags, int prime, int valrec)) { if(fptr == &mesh_detect_cycle) return 1; return 0; diff --git a/util/fptr_wlist.h b/util/fptr_wlist.h index 62692ba8b53..10de5d81677 100644 --- a/util/fptr_wlist.h +++ b/util/fptr_wlist.h @@ -233,7 +233,7 @@ int fptr_whitelist_modenv_detach_subs(void (*fptr)( */ int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, struct module_qstate** newq)); + uint16_t qflags, int prime, int valrec, struct module_qstate** newq)); /** * Check function pointer whitelist for module_env kill_sub callback values. @@ -251,7 +251,7 @@ int fptr_whitelist_modenv_kill_sub(void (*fptr)(struct module_qstate* newq)); */ int fptr_whitelist_modenv_detect_cycle(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t flags, int prime)); + uint16_t flags, int prime, int valrec)); /** * Check function pointer whitelist for module init call values. diff --git a/util/iana_ports.inc b/util/iana_ports.inc index ff971293fe9..d318477e56f 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -2061,6 +2061,7 @@ 2423, 2424, 2425, +2426, 2427, 2428, 2429, @@ -5353,9 +5354,11 @@ 35004, 35355, 36001, +36411, 36865, 37475, 37654, +38002, 38201, 38202, 38203, diff --git a/util/module.h b/util/module.h index f95ff6dc837..b9dde36e2f3 100644 --- a/util/module.h +++ b/util/module.h @@ -256,13 +256,14 @@ struct module_env { * @param qinfo: what to query for (copied). * @param qflags: what flags to use (RD, CD flag or not). * @param prime: if it is a (stub) priming query. + * @param valrec: validation lookup recursion, does not need validation * @param newq: If the new subquery needs initialisation, it is * returned, otherwise NULL is returned. * @return: false on error, true if success (and init may be needed). */ int (*attach_sub)(struct module_qstate* qstate, struct query_info* qinfo, uint16_t qflags, int prime, - struct module_qstate** newq); + int valrec, struct module_qstate** newq); /** * Kill newly attached sub. If attach_sub returns newq for @@ -280,13 +281,15 @@ struct module_env { * @param qinfo: query info for dependency. * @param flags: query flags of dependency, RD/CD flags. * @param prime: if dependency is a priming query or not. + * @param valrec: validation lookup recursion, does not need validation * @return true if the name,type,class exists and the given * qstate mesh exists as a dependency of that name. Thus * if qstate becomes dependent on name,type,class then a * cycle is created. */ int (*detect_cycle)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t flags, int prime); + struct query_info* qinfo, uint16_t flags, int prime, + int valrec); /** region for temporary usage. May be cleared after operate() call. */ struct regional* scratch; @@ -397,6 +400,9 @@ struct module_qstate { uint16_t query_flags; /** if this is a (stub or root) priming query (with hints) */ int is_priming; + /** if this is a validation recursion query that does not get + * validation itself */ + int is_valrec; /** comm_reply contains server replies */ struct comm_reply* reply; diff --git a/util/net_help.c b/util/net_help.c index 49ce677f4aa..8c2bac7372f 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -699,7 +699,7 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem) } } if(verifypem && verifypem[0]) { - if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL) != 1) { + if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_crypto_err("error in SSL_CTX verify"); SSL_CTX_free(ctx); return NULL; diff --git a/validator/validator.c b/validator/validator.c index aefa26a2794..9d5d5c39025 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -283,12 +283,25 @@ needs_validation(struct module_qstate* qstate, int ret_rc, { int rcode; - /* If the CD bit is on in the original request, then we don't bother to - * validate anything.*/ + /* If the CD bit is on in the original request, then you could think + * that we don't bother to validate anything. + * But this is signalled internally with the valrec flag. + * User queries are validated with BIT_CD to make our cache clean + * so that bogus messages get retried by the upstream also for + * downstream validators that set BIT_CD. + * For DNS64 bit_cd signals no dns64 processing, but we want to + * provide validation there too */ + /* if(qstate->query_flags & BIT_CD) { verbose(VERB_ALGO, "not validating response due to CD bit"); return 0; } + */ + if(qstate->is_valrec) { + verbose(VERB_ALGO, "not validating response, is valrec" + "(validation recursion lookup)"); + return 0; + } if(ret_rc != LDNS_RCODE_NOERROR || !ret_msg) rcode = ret_rc; @@ -351,14 +364,20 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name, struct val_qstate* vq = (struct val_qstate*)qstate->minfo[id]; struct module_qstate* newq; struct query_info ask; + int valrec; ask.qname = name; ask.qname_len = namelen; ask.qtype = qtype; ask.qclass = qclass; log_query_info(VERB_ALGO, "generate request", &ask); fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); + /* enable valrec flag to avoid recursion to the same validation + * routine, this lookup is simply a lookup. DLVs need validation */ + if(qtype == LDNS_RR_TYPE_DLV) + valrec = 0; + else valrec = 1; if(!(*qstate->env->attach_sub)(qstate, &ask, - (uint16_t)(BIT_RD|flags), 0, &newq)){ + (uint16_t)(BIT_RD|flags), 0, valrec, &newq)){ log_err("Could not generate request: out of memory"); return 0; } @@ -2005,14 +2024,16 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, /* if secure, this will override cache anyway, no need * to check if from parentNS */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, - vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) { + vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, + qstate->query_flags)) { log_err("out of memory caching validator results"); } } else { /* for a referral, store the verified RRsets */ /* and this does not get prefetched, so no leeway */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, - vq->orig_msg->rep, 1, 0, 0, NULL)) { + vq->orig_msg->rep, 1, 0, 0, NULL, + qstate->query_flags)) { log_err("out of memory caching validator results"); } }