diff options
author | Stuart Henderson <sthen@cvs.openbsd.org> | 2012-03-26 18:05:45 +0000 |
---|---|---|
committer | Stuart Henderson <sthen@cvs.openbsd.org> | 2012-03-26 18:05:45 +0000 |
commit | dae82d183ea6d5e2746b6d132b6da1637a2db718 (patch) | |
tree | 65008e4c044690c8ea7f370282bb0bbf349e8cfc /usr.sbin | |
parent | ef291430e2204dceca880cbb9640762e2d49bceb (diff) |
Import Unbound 1.4.16 to work on in-tree (not yet linked to the build).
These are the direct sources from NLnet Labs upstream, minus these:
compat contrib libunbound/python pythonmod testcode testdata winrc
ok deraadt@ jakob@
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/unbound/aclocal.m4 | 307 | ||||
-rw-r--r--[-rwxr-xr-x] | usr.sbin/unbound/install-sh | 35 | ||||
-rw-r--r-- | usr.sbin/unbound/libunbound/ubsyms.def | 4 | ||||
-rw-r--r-- | usr.sbin/unbound/libunbound/unbound.h | 83 | ||||
-rw-r--r-- | usr.sbin/unbound/services/localzone.c | 446 | ||||
-rw-r--r-- | usr.sbin/unbound/services/outside_network.c | 483 | ||||
-rw-r--r-- | usr.sbin/unbound/services/outside_network.h | 90 | ||||
-rw-r--r-- | usr.sbin/unbound/util/data/packed_rrset.c | 229 | ||||
-rw-r--r-- | usr.sbin/unbound/util/mini_event.c | 24 | ||||
-rw-r--r-- | usr.sbin/unbound/util/tube.c | 25 | ||||
-rw-r--r-- | usr.sbin/unbound/util/winsock_event.c | 42 | ||||
-rw-r--r-- | usr.sbin/unbound/validator/val_anchor.c | 466 |
12 files changed, 922 insertions, 1312 deletions
diff --git a/usr.sbin/unbound/aclocal.m4 b/usr.sbin/unbound/aclocal.m4 index a50a63068e2..de630d85b48 100644 --- a/usr.sbin/unbound/aclocal.m4 +++ b/usr.sbin/unbound/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.13.4 -*- Autoconf -*- - -# Copyright (C) 1996-2013 Free Software Foundation, Inc. +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,12 +11,11 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -25,8 +24,8 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008, 2009, 2010, 2011 Free Software -# Foundation, Inc. +# 2006, 2007, 2008, 2009, 2010 Free Software Foundation, +# Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. @@ -160,8 +159,6 @@ AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl -_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl -dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl @@ -647,7 +644,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. -Copyright (C) 2011 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." @@ -811,7 +808,6 @@ AC_DEFUN([LT_LANG], m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], - [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], @@ -833,29 +829,6 @@ m4_defun([_LT_LANG], ])# _LT_LANG -m4_ifndef([AC_PROG_GO], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_GO. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -m4_defun([AC_PROG_GO], -[AC_LANG_PUSH(Go)dnl -AC_ARG_VAR([GOC], [Go compiler command])dnl -AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl -_AC_ARG_VAR_LDFLAGS()dnl -AC_CHECK_TOOL(GOC, gccgo) -if test -z "$GOC"; then - if test -n "$ac_tool_prefix"; then - AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) - fi -fi -if test -z "$GOC"; then - AC_CHECK_PROG(GOC, gccgo, gccgo, false) -fi -])#m4_defun -])#m4_ifndef - - # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], @@ -886,10 +859,6 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ], m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) -AC_PROVIDE_IFELSE([AC_PROG_GO], - [LT_LANG(GO)], - [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) - AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) @@ -992,13 +961,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? - # If there is a non-empty error log, and "single_module" - # appears in it, assume the flag caused a linker warning - if test -s conftest.err && $GREP single_module conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - # Otherwise, if the output was created with a 0 exit code from - # the compiler, it worked. - elif test -f libconftest.dylib && test $_lt_result -eq 0; then + if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1006,7 +969,6 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ rm -rf libconftest.dylib* rm -f conftest.* fi]) - AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no @@ -1018,7 +980,6 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) - AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF @@ -1036,9 +997,7 @@ _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? - if test -s conftest.err && $GREP force_load conftest.err; then - cat conftest.err >&AS_MESSAGE_LOG_FD - elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then + if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD @@ -1083,8 +1042,8 @@ _LT_EOF ]) -# _LT_DARWIN_LINKER_FEATURES([TAG]) -# --------------------------------- +# _LT_DARWIN_LINKER_FEATURES +# -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ @@ -1095,8 +1054,6 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' - m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], - [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi @@ -1318,7 +1275,7 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext @@ -1332,10 +1289,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; - powerpc64le-*linux*) - LD="${LD-ld} -m elf32lppclinux" - ;; - powerpc64-*linux*) + ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) @@ -1354,10 +1308,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; - powerpcle-*linux*) - LD="${LD-ld} -m elf64lppc" - ;; - powerpc-*linux*) + ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) @@ -1386,27 +1337,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) CFLAGS="$SAVE_CFLAGS" fi ;; -*-*solaris*) +sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in - yes*) - case $host in - i?86-*-solaris*) - LD="${LD-ld} -m elf_x86_64" - ;; - sparc*-*-solaris*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - # GNU ld 2.21 introduced _sol2 emulations. Use them if available. - if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then - LD="${LD-ld}_sol2" - fi - ;; + yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" @@ -1483,13 +1421,13 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi case $host_os in @@ -1669,11 +1607,6 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl lt_cv_sys_max_cmd_len=196608 ;; - os2*) - # The test takes a long time on OS/2. - lt_cv_sys_max_cmd_len=8192 - ;; - osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -1713,7 +1646,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. - while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ + while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do @@ -2259,7 +2192,7 @@ need_version=unknown case $host_os in aix3*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH @@ -2268,7 +2201,7 @@ aix3*) ;; aix[[4-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes @@ -2333,7 +2266,7 @@ beos*) ;; bsdi[[45]]*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -2472,7 +2405,7 @@ m4_if([$1], [],[ ;; dgux*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' @@ -2480,6 +2413,10 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; +freebsd1*) + dynamic_linker=no + ;; + freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. @@ -2487,7 +2424,7 @@ freebsd* | dragonfly*) objformat=`/usr/bin/objformat` else case $host_os in - freebsd[[23]].*) objformat=aout ;; + freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi @@ -2505,7 +2442,7 @@ freebsd* | dragonfly*) esac shlibpath_var=LD_LIBRARY_PATH case $host_os in - freebsd2.*) + freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) @@ -2525,18 +2462,17 @@ freebsd* | dragonfly*) ;; gnu*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; haiku*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" @@ -2597,7 +2533,7 @@ hpux9* | hpux10* | hpux11*) ;; interix[[3-9]]*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' @@ -2613,7 +2549,7 @@ irix5* | irix6* | nonstopux*) nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux else version_type=irix fi ;; @@ -2650,9 +2586,9 @@ linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; -# This must be glibc/ELF. +# This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2719,7 +2655,7 @@ netbsd*) ;; newsos6) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes @@ -2788,7 +2724,7 @@ rdos*) ;; solaris*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2813,7 +2749,7 @@ sunos4*) ;; sysv4 | sysv4.3*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -2837,7 +2773,7 @@ sysv4 | sysv4.3*) sysv4*MP*) if test -d /usr/nec ;then - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH @@ -2868,7 +2804,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -2878,7 +2814,7 @@ tpf*) ;; uts4*) - version_type=linux # correct to gnu/linux during the next big refactor + version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -3300,7 +3236,7 @@ irix5* | irix6* | nonstopux*) lt_cv_deplibs_check_method=pass_all ;; -# This must be glibc/ELF. +# This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -3720,7 +3656,6 @@ for ac_symprfx in "" "_"; do # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ -" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ @@ -4305,9 +4240,7 @@ m4_if([$1], [CXX], [ case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' - if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then - _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" - fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Xcompiler -fPIC' ;; esac else @@ -4399,33 +4332,18 @@ m4_if([$1], [CXX], [ ;; *) case `$CC -V 2>&1 | sed 5q` in - *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + *Sun\ F* | *Sun*Fortran*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; - *Sun\ F* | *Sun*Fortran*) - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' - ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; - *Intel*\ [[CF]]*Compiler*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' - ;; - *Portland\ Group*) - _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' - ;; esac ;; esac @@ -4585,9 +4503,7 @@ m4_if([$1], [CXX], [ ;; cygwin* | mingw* | cegcc*) case $cc_basename in - cl*) - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' - ;; + cl*) ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] @@ -4612,6 +4528,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -4862,7 +4779,8 @@ _LT_EOF xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ @@ -5157,7 +5075,6 @@ _LT_EOF # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' @@ -5204,6 +5121,10 @@ _LT_EOF _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; + freebsd1*) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little @@ -5216,7 +5137,7 @@ _LT_EOF ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2.*) + freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes @@ -5255,6 +5176,7 @@ _LT_EOF fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes @@ -5696,6 +5618,9 @@ _LT_TAGDECL([], [no_undefined_flag], [1], _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], + [[If ld is used when linking, flag to hardcode $libdir into a binary + during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], @@ -5849,6 +5774,7 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported @@ -6218,7 +6144,7 @@ if test "$_lt_caught_CXX_error" != yes; then esac ;; - freebsd2.*) + freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no @@ -6979,18 +6905,12 @@ public class foo { } }; _LT_EOF -], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF -package foo -func foo() { -} -_LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; -*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary @@ -7187,6 +7107,7 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7319,6 +7240,7 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no @@ -7501,73 +7423,6 @@ CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG -# _LT_LANG_GO_CONFIG([TAG]) -# -------------------------- -# Ensure that the configuration variables for the GNU Go compiler -# are suitably defined. These variables are subsequently used by _LT_CONFIG -# to write the compiler configuration to `libtool'. -m4_defun([_LT_LANG_GO_CONFIG], -[AC_REQUIRE([LT_PROG_GO])dnl -AC_LANG_SAVE - -# Source file extension for Go test sources. -ac_ext=go - -# Object file extension for compiled Go test sources. -objext=o -_LT_TAGVAR(objext, $1)=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="package main; func main() { }" - -# Code to be used in simple link tests -lt_simple_link_test_code='package main; func main() { }' - -# ltmain only uses $CC for tagged configurations so make sure $CC is set. -_LT_TAG_COMPILER - -# save warnings/boilerplate of simple test code -_LT_COMPILER_BOILERPLATE -_LT_LINKER_BOILERPLATE - -# Allow CC to be a program name with arguments. -lt_save_CC=$CC -lt_save_CFLAGS=$CFLAGS -lt_save_GCC=$GCC -GCC=yes -CC=${GOC-"gccgo"} -CFLAGS=$GOFLAGS -compiler=$CC -_LT_TAGVAR(compiler, $1)=$CC -_LT_TAGVAR(LD, $1)="$LD" -_LT_CC_BASENAME([$compiler]) - -# Go did not exist at the time GCC didn't implicitly link libc in. -_LT_TAGVAR(archive_cmds_need_lc, $1)=no - -_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds -_LT_TAGVAR(reload_flag, $1)=$reload_flag -_LT_TAGVAR(reload_cmds, $1)=$reload_cmds - -if test -n "$compiler"; then - _LT_COMPILER_NO_RTTI($1) - _LT_COMPILER_PIC($1) - _LT_COMPILER_C_O($1) - _LT_COMPILER_FILE_LOCKS($1) - _LT_LINKER_SHLIBS($1) - _LT_LINKER_HARDCODE_LIBPATH($1) - - _LT_CONFIG($1) -fi - -AC_LANG_RESTORE - -GCC=$lt_save_GCC -CC=$lt_save_CC -CFLAGS=$lt_save_CFLAGS -])# _LT_LANG_GO_CONFIG - - # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler @@ -7637,13 +7492,6 @@ dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) -# LT_PROG_GO -# ---------- -AC_DEFUN([LT_PROG_GO], -[AC_CHECK_TOOL(GOC, gccgo,) -]) - - # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], @@ -8308,24 +8156,9 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], - [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for lt_pkg in $withval; do - IFS="$lt_save_ifs" - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac], + [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) @@ -8497,15 +8330,15 @@ m4_define([lt_dict_filter], # @configure_input@ -# serial 3337 ltversion.m4 +# serial 3293 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.2]) -m4_define([LT_PACKAGE_REVISION], [1.3337]) +m4_define([LT_PACKAGE_VERSION], [2.4]) +m4_define([LT_PACKAGE_REVISION], [1.3293]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.2' -macro_revision='1.3337' +[macro_version='2.4' +macro_revision='1.3293' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) diff --git a/usr.sbin/unbound/install-sh b/usr.sbin/unbound/install-sh index 377bb8687ff..6781b987bdb 100755..100644 --- a/usr.sbin/unbound/install-sh +++ b/usr.sbin/unbound/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -35,7 +35,7 @@ scriptversion=2011-11-20.07; # UTC # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it +# `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written @@ -156,10 +156,6 @@ while test $# -ne 0; do -s) stripcmd=$stripprog;; -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac shift;; -T) no_target_directory=true;; @@ -190,10 +186,6 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then fi shift # arg dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac done fi @@ -202,17 +194,13 @@ if test $# -eq 0; then echo "$0: no input file specified." >&2 exit 1 fi - # It's OK to call 'install-sh -d' without argument. + # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 + trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. @@ -240,9 +228,9 @@ fi for src do - # Protect names problematic for 'test' and other utilities. + # Protect names starting with `-'. case $src in - -* | [=\(\)!]) src=./$src;; + -*) src=./$src;; esac if test -n "$dir_arg"; then @@ -264,7 +252,12 @@ do echo "$0: no destination specified." >&2 exit 1 fi + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. @@ -354,7 +347,7 @@ do if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. + # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in @@ -392,7 +385,7 @@ do case $dstdir in /*) prefix='/';; - [-=\(\)!]*) prefix='./';; + -*) prefix='./';; *) prefix='';; esac @@ -410,7 +403,7 @@ do for d do - test X"$d" = X && continue + test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then diff --git a/usr.sbin/unbound/libunbound/ubsyms.def b/usr.sbin/unbound/libunbound/ubsyms.def index ff3d9587b7c..7e3fdd1e25e 100644 --- a/usr.sbin/unbound/libunbound/ubsyms.def +++ b/usr.sbin/unbound/libunbound/ubsyms.def @@ -1,5 +1,4 @@ ub_ctx_create -ub_ctx_create_event ub_ctx_delete ub_ctx_get_option ub_ctx_set_option @@ -8,7 +7,6 @@ ub_ctx_set_fwd ub_ctx_resolvconf ub_ctx_hosts ub_ctx_add_ta -ub_ctx_add_ta_autr ub_ctx_add_ta_file ub_ctx_trustedkeys ub_ctx_debugout @@ -20,7 +18,6 @@ ub_fd ub_process ub_resolve ub_resolve_async -ub_resolve_event ub_cancel ub_resolve_free ub_strerror @@ -30,4 +27,3 @@ ub_ctx_zone_remove ub_ctx_data_add ub_ctx_data_remove ub_version -ub_ctx_set_event diff --git a/usr.sbin/unbound/libunbound/unbound.h b/usr.sbin/unbound/libunbound/unbound.h index fe903d0c51d..085f9f53415 100644 --- a/usr.sbin/unbound/libunbound/unbound.h +++ b/usr.sbin/unbound/libunbound/unbound.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -78,10 +78,6 @@ * ... same as async for non-threaded * ... the callbacks are called in the thread that calls process(ctx) * - * Openssl needs to have locking in place, and the application must set - * it up, because a mere library cannot do this, use the calls - * CRYPTO_set_id_callback and CRYPTO_set_locking_callback. - * * If no threading is compiled in, the above async example uses fork(2) to * create a process to perform the work. The forked process exits when the * calling process exits, or ctx_delete() is called. @@ -101,11 +97,6 @@ extern "C" { #endif -/** the version of this header file */ -#define UNBOUND_VERSION_MAJOR @UNBOUND_VERSION_MAJOR@ -#define UNBOUND_VERSION_MINOR @UNBOUND_VERSION_MINOR@ -#define UNBOUND_VERSION_MICRO @UNBOUND_VERSION_MICRO@ - /** * The validation context is created to hold the resolver status, * validation keys and a small cache (containing messages, rrsets, @@ -202,12 +193,6 @@ struct ub_result { * Is NULL if the result is not bogus. */ char* why_bogus; - - /** - * TTL for the result, in seconds. If the security is bogus, then - * you also cannot trust this value. - */ - int ttl; }; /** @@ -254,7 +239,7 @@ void ub_ctx_delete(struct ub_ctx* ctx); * @param val: value of the option. * @return: 0 if OK, else error. */ -int ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val); +int ub_ctx_set_option(struct ub_ctx* ctx, char* opt, char* val); /** * Get an option from the context. @@ -270,7 +255,7 @@ int ub_ctx_set_option(struct ub_ctx* ctx, const char* opt, const char* val); * returned in the string. * @return 0 if OK else an error code (malloc failure, syntax error). */ -int ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str); +int ub_ctx_get_option(struct ub_ctx* ctx, char* opt, char** str); /** * setup configuration for the given context. @@ -282,7 +267,7 @@ int ub_ctx_get_option(struct ub_ctx* ctx, const char* opt, char** str); * routines exist. * @return: 0 if OK, else error. */ -int ub_ctx_config(struct ub_ctx* ctx, const char* fname); +int ub_ctx_config(struct ub_ctx* ctx, char* fname); /** * Set machine to forward DNS queries to, the caching resolver to use. @@ -301,7 +286,7 @@ int ub_ctx_config(struct ub_ctx* ctx, const char* fname); * If the addr is NULL, forwarding is disabled. * @return 0 if OK, else error. */ -int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr); +int ub_ctx_set_fwd(struct ub_ctx* ctx, char* addr); /** * Read list of nameservers to use from the filename given. @@ -317,7 +302,7 @@ int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr); * @param fname: file name string. If NULL "/etc/resolv.conf" is used. * @return 0 if OK, else error. */ -int ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname); +int ub_ctx_resolvconf(struct ub_ctx* ctx, char* fname); /** * Read list of hosts from the filename given. @@ -330,7 +315,7 @@ int ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname); * @param fname: file name string. If NULL "/etc/hosts" is used. * @return 0 if OK, else error. */ -int ub_ctx_hosts(struct ub_ctx* ctx, const char* fname); +int ub_ctx_hosts(struct ub_ctx* ctx, char* fname); /** * Add a trust anchor to the given context. @@ -343,7 +328,7 @@ int ub_ctx_hosts(struct ub_ctx* ctx, const char* fname); * [domainname] [TTL optional] [type] [class optional] [rdata contents] * @return 0 if OK, else error. */ -int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta); +int ub_ctx_add_ta(struct ub_ctx* ctx, char* ta); /** * Add trust anchors to the given context. @@ -354,22 +339,7 @@ int ub_ctx_add_ta(struct ub_ctx* ctx, const char* ta); * @param fname: filename of file with keyfile with trust anchors. * @return 0 if OK, else error. */ -int ub_ctx_add_ta_file(struct ub_ctx* ctx, const char* fname); - -/** - * 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, - * or you can start it by providing a trusted DNSKEY or DS record on one - * line in the file. - * @param ctx: context. - * At this time it is only possible to add trusted keys before the - * first resolve is done. - * @param fname: filename of file with trust anchor. - * @return 0 if OK, else error. - */ -int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname); +int ub_ctx_add_ta_file(struct ub_ctx* ctx, char* fname); /** * Add trust anchors to the given context. @@ -381,7 +351,7 @@ int ub_ctx_add_ta_autr(struct ub_ctx* ctx, const char* fname); * anchors. * @return 0 if OK, else error. */ -int ub_ctx_trustedkeys(struct ub_ctx* ctx, const char* fname); +int ub_ctx_trustedkeys(struct ub_ctx* ctx, char* fname); /** * Set debug output (and error output) to the specified stream. @@ -466,7 +436,7 @@ int ub_process(struct ub_ctx* ctx); * in that case (out of memory). * @return 0 if OK, else error. */ -int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, +int ub_resolve(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, struct ub_result** result); /** @@ -497,7 +467,7 @@ int ub_resolve(struct ub_ctx* ctx, const char* name, int rrtype, * cancel the query. * @return 0 if OK, else error. */ -int ub_resolve_async(struct ub_ctx* ctx, const char* name, int rrtype, +int ub_resolve_async(struct ub_ctx* ctx, char* name, int rrtype, int rrclass, void* mydata, ub_callback_t callback, int* async_id); /** @@ -523,7 +493,7 @@ void ub_resolve_free(struct ub_result* result); /** * Convert error value to a human readable string. - * @param err: error code from one of the libunbound functions. + * @param err: error code from one of the ub_val* functions. * @return pointer to constant text string, zero terminated. */ const char* ub_strerror(int err); @@ -544,8 +514,7 @@ int ub_ctx_print_local_zones(struct ub_ctx* ctx); * @param zone_type: type of the zone (like for unbound.conf) in text. * @return 0 if OK, else error. */ -int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, - const char *zone_type); +int ub_ctx_zone_add(struct ub_ctx* ctx, char *zone_name, char *zone_type); /** * Remove zone from local authority info of the library. @@ -554,7 +523,7 @@ int ub_ctx_zone_add(struct ub_ctx* ctx, const char *zone_name, * If it does not exist, nothing happens. * @return 0 if OK, else error. */ -int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name); +int ub_ctx_zone_remove(struct ub_ctx* ctx, char *zone_name); /** * Add localdata to the library local authority info. @@ -564,7 +533,7 @@ int ub_ctx_zone_remove(struct ub_ctx* ctx, const char *zone_name); * "www.example.com IN A 127.0.0.1" * @return 0 if OK, else error. */ -int ub_ctx_data_add(struct ub_ctx* ctx, const char *data); +int ub_ctx_data_add(struct ub_ctx* ctx, char *data); /** * Remove localdata from the library local authority info. @@ -572,7 +541,7 @@ int ub_ctx_data_add(struct ub_ctx* ctx, const char *data); * @param data: the name to delete all data from, like "www.example.com". * @return 0 if OK, else error. */ -int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data); +int ub_ctx_data_remove(struct ub_ctx* ctx, char *data); /** * Get a version string from the libunbound implementation. diff --git a/usr.sbin/unbound/services/localzone.c b/usr.sbin/unbound/services/localzone.c index c50ad0f1586..98d69433e30 100644 --- a/usr.sbin/unbound/services/localzone.c +++ b/usr.sbin/unbound/services/localzone.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -39,16 +39,15 @@ * This file contains functions to enable local zone authority service. */ #include "config.h" +#include <ldns/dname.h> +#include <ldns/host2wire.h> #include "services/localzone.h" -#include "sldns/str2wire.h" -#include "sldns/sbuffer.h" #include "util/regional.h" #include "util/config_file.h" #include "util/data/dname.h" #include "util/data/packed_rrset.h" #include "util/data/msgencode.h" #include "util/net_help.h" -#include "util/netevent.h" #include "util/data/msgreply.h" #include "util/data/msgparse.h" @@ -60,7 +59,7 @@ local_zones_create(void) if(!zones) return NULL; rbtree_init(&zones->ztree, &local_zone_cmp); - lock_rw_init(&zones->lock); + lock_quick_init(&zones->lock); lock_protect(&zones->lock, &zones->ztree, sizeof(zones->ztree)); /* also lock protects the rbnode's in struct local_zone */ return zones; @@ -79,7 +78,7 @@ local_zones_delete(struct local_zones* zones) { if(!zones) return; - lock_rw_destroy(&zones->lock); + lock_quick_destroy(&zones->lock); /* walk through zones and delete them all */ traverse_postorder(&zones->ztree, lzdel, NULL); free(zones); @@ -126,12 +125,21 @@ local_data_cmp(const void* d1, const void* d2) int parse_dname(const char* str, uint8_t** res, size_t* len, int* labs) { - *res = sldns_str2wire_dname(str, len); + ldns_rdf* rdf; + *res = NULL; + *len = 0; *labs = 0; - if(!*res) { + rdf = ldns_dname_new_frm_str(str); + if(!rdf) { log_err("cannot parse name %s", str); return 0; } + *res = memdup(ldns_rdf_data(rdf), ldns_rdf_size(rdf)); + ldns_rdf_deep_free(rdf); + if(!*res) { + log_err("out of memory"); + return 0; + } *labs = dname_count_size_labels(*res, len); return 1; } @@ -175,16 +183,16 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, } /* add to rbtree */ - lock_rw_wrlock(&zones->lock); + lock_quick_lock(&zones->lock); lock_rw_wrlock(&z->lock); if(!rbtree_insert(&zones->ztree, &z->node)) { log_warn("duplicate local-zone"); lock_rw_unlock(&z->lock); local_zone_delete(z); - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); return NULL; } - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); return z; } @@ -217,28 +225,39 @@ lz_enter_zone(struct local_zones* zones, const char* name, const char* type, /** return name and class and rdata of rr; parses string */ static int get_rr_content(const char* str, uint8_t** nm, uint16_t* type, - uint16_t* dclass, time_t* ttl, uint8_t* rr, size_t len, - uint8_t** rdata, size_t* rdata_len) + uint16_t* dclass, uint32_t* ttl, ldns_buffer* rdata) { - size_t dname_len = 0; - int e = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, - NULL, 0, NULL, 0); - if(e) { - log_err("error parsing local-data at %d: '%s': %s", - LDNS_WIREPARSE_OFFSET(e), str, - sldns_get_errorstr_parse(e)); + ldns_rr* rr = NULL; + ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL); + if(status != LDNS_STATUS_OK) { + log_err("error parsing local-data '%s': %s", + str, ldns_get_errorstr_by_id(status)); + ldns_rr_free(rr); return 0; } - *nm = memdup(rr, dname_len); + *nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)), + ldns_rdf_size(ldns_rr_owner(rr))); if(!*nm) { log_err("out of memory"); + ldns_rr_free(rr); return 0; } - *dclass = sldns_wirerr_get_class(rr, len, dname_len); - *type = sldns_wirerr_get_type(rr, len, dname_len); - *ttl = (time_t)sldns_wirerr_get_ttl(rr, len, dname_len); - *rdata = sldns_wirerr_get_rdatawl(rr, len, dname_len); - *rdata_len = sldns_wirerr_get_rdatalen(rr, len, dname_len)+2; + *dclass = ldns_rr_get_class(rr); + *type = ldns_rr_get_type(rr); + *ttl = (uint32_t)ldns_rr_ttl(rr); + ldns_buffer_clear(rdata); + ldns_buffer_skip(rdata, 2); + status = ldns_rr_rdata2buffer_wire(rdata, rr); + ldns_rr_free(rr); + if(status != LDNS_STATUS_OK) { + log_err("error converting RR '%s' to wireformat: %s", + str, ldns_get_errorstr_by_id(status)); + free(*nm); + *nm = NULL; + return 0; + } + ldns_buffer_flip(rdata); + ldns_buffer_write_u16_at(rdata, 0, ldns_buffer_limit(rdata) - 2); return 1; } @@ -246,18 +265,18 @@ get_rr_content(const char* str, uint8_t** nm, uint16_t* type, static int get_rr_nameclass(const char* str, uint8_t** nm, uint16_t* dclass) { - uint8_t rr[LDNS_RR_BUF_SIZE]; - size_t len = sizeof(rr), dname_len = 0; - int s = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, 3600, - NULL, 0, NULL, 0); - if(s != 0) { - log_err("error parsing local-data at %d '%s': %s", - LDNS_WIREPARSE_OFFSET(s), str, - sldns_get_errorstr_parse(s)); + ldns_rr* rr = NULL; + ldns_status status = ldns_rr_new_frm_str(&rr, str, 3600, NULL, NULL); + if(status != LDNS_STATUS_OK) { + log_err("error parsing local-data '%s': %s", + str, ldns_get_errorstr_by_id(status)); + ldns_rr_free(rr); return 0; } - *nm = memdup(rr, dname_len); - *dclass = sldns_wirerr_get_class(rr, len, dname_len); + *nm = memdup(ldns_rdf_data(ldns_rr_owner(rr)), + ldns_rdf_size(ldns_rr_owner(rr))); + *dclass = ldns_rr_get_class(rr); + ldns_rr_free(rr); if(!*nm) { log_err("out of memory"); return 0; @@ -285,12 +304,13 @@ local_data_find_type(struct local_data* data, uint16_t type) /** check for RR duplicates */ static int -rr_is_duplicate(struct packed_rrset_data* pd, uint8_t* rdata, size_t rdata_len) +rr_is_duplicate(struct packed_rrset_data* pd, ldns_buffer* buf) { size_t i; for(i=0; i<pd->count; i++) { - if(pd->rr_len[i] == rdata_len && - memcmp(pd->rr_data[i], rdata, rdata_len) == 0) + if(ldns_buffer_limit(buf) == pd->rr_len[i] && + memcmp(ldns_buffer_begin(buf), pd->rr_data[i], + ldns_buffer_limit(buf)) == 0) return 1; } return 0; @@ -336,10 +356,10 @@ new_local_rrset(struct regional* region, struct local_data* node, /** insert RR into RRset data structure; Wastes a couple of bytes */ static int insert_rr(struct regional* region, struct packed_rrset_data* pd, - uint8_t* rdata, size_t rdata_len, time_t ttl) + ldns_buffer* buf, uint32_t ttl) { size_t* oldlen = pd->rr_len; - time_t* oldttl = pd->rr_ttl; + uint32_t* oldttl = pd->rr_ttl; uint8_t** olddata = pd->rr_data; /* add RR to rrset */ @@ -359,9 +379,10 @@ insert_rr(struct regional* region, struct packed_rrset_data* pd, memcpy(pd->rr_data+1, olddata, sizeof(*pd->rr_data)*(pd->count-1)); } - pd->rr_len[0] = rdata_len; + pd->rr_len[0] = ldns_buffer_limit(buf); pd->rr_ttl[0] = ttl; - pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len); + pd->rr_data[0] = regional_alloc_init(region, + ldns_buffer_begin(buf), ldns_buffer_limit(buf)); if(!pd->rr_data[0]) { log_err("out of memory"); return 0; @@ -419,7 +440,8 @@ lz_find_create_node(struct local_zone* z, uint8_t* nm, size_t nmlen, /** enter data RR into auth zone */ static int -lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) +lz_enter_rr_into_zone(struct local_zone* z, ldns_buffer* buf, + const char* rrstr) { uint8_t* nm; size_t nmlen; @@ -427,13 +449,9 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) struct local_data* node; struct local_rrset* rrset; struct packed_rrset_data* pd; - uint16_t rrtype = 0, rrclass = 0; - time_t ttl = 0; - uint8_t rr[LDNS_RR_BUF_SIZE]; - uint8_t* rdata; - size_t rdata_len; - if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, rr, sizeof(rr), - &rdata, &rdata_len)) { + uint16_t rrtype, rrclass; + uint32_t ttl; + if(!get_rr_content(rrstr, &nm, &rrtype, &rrclass, &ttl, buf)) { log_err("bad local-data: %s", rrstr); return 0; } @@ -469,16 +487,16 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) log_assert(rrset && pd); /* check for duplicate RR */ - if(rr_is_duplicate(pd, rdata, rdata_len)) { + if(rr_is_duplicate(pd, buf)) { verbose(VERB_ALGO, "ignoring duplicate RR: %s", rrstr); return 1; } - return insert_rr(z->region, pd, rdata, rdata_len, ttl); + return insert_rr(z->region, pd, buf, ttl); } /** enter a data RR into auth data; a zone for it must exist */ static int -lz_enter_rr_str(struct local_zones* zones, const char* rr) +lz_enter_rr_str(struct local_zones* zones, const char* rr, ldns_buffer* buf) { uint8_t* rr_name; uint16_t rr_class; @@ -491,16 +509,16 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr) return 0; } labs = dname_count_size_labels(rr_name, &len); - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); z = local_zones_lookup(zones, rr_name, len, labs, rr_class); if(!z) { - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); fatal_exit("internal error: no zone for rr %s", rr); } lock_rw_wrlock(&z->lock); - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); free(rr_name); - r = lz_enter_rr_into_zone(z, rr); + r = lz_enter_rr_into_zone(z, buf, rr); lock_rw_unlock(&z->lock); return r; } @@ -531,13 +549,13 @@ lz_exists(struct local_zones* zones, const char* name) log_err("bad name %s", name); return 0; } - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); if(rbtree_search(&zones->ztree, &z.node)) { - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); free(z.name); return 1; } - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); free(z.name); return 0; } @@ -564,7 +582,7 @@ lz_nodefault(struct config_file* cfg, const char* name) /** enter AS112 default zone */ static int add_as112_default(struct local_zones* zones, struct config_file* cfg, - const char* name) + ldns_buffer* buf, const char* name) { struct local_zone* z; char str[1024]; /* known long enough */ @@ -574,12 +592,12 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg, return 0; snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800", name); - if(!lz_enter_rr_into_zone(z, str)) { + if(!lz_enter_rr_into_zone(z, buf, str)) { lock_rw_unlock(&z->lock); return 0; } snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); - if(!lz_enter_rr_into_zone(z, str)) { + if(!lz_enter_rr_into_zone(z, buf, str)) { lock_rw_unlock(&z->lock); return 0; } @@ -589,27 +607,26 @@ add_as112_default(struct local_zones* zones, struct config_file* cfg, /** enter default zones */ static int -lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) +lz_enter_defaults(struct local_zones* zones, struct config_file* cfg, + ldns_buffer* buf) { struct local_zone* z; /* this list of zones is from RFC 6303 */ - /* block localhost level zones, first, later the LAN zones */ - /* localhost. zone */ if(!lz_exists(zones, "localhost.") && !lz_nodefault(cfg, "localhost.")) { if(!(z=lz_enter_zone(zones, "localhost.", "static", LDNS_RR_CLASS_IN)) || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "localhost. 10800 IN NS localhost.") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "localhost. 10800 IN SOA localhost. nobody.invalid. " "1 3600 1200 604800 10800") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "localhost. 10800 IN A 127.0.0.1") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "localhost. 10800 IN AAAA ::1")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } @@ -622,12 +639,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) !lz_nodefault(cfg, "127.in-addr.arpa.")) { if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", LDNS_RR_CLASS_IN)) || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "127.in-addr.arpa. 10800 IN NS localhost.") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "127.in-addr.arpa. 10800 IN SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } @@ -640,12 +657,12 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) !lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) { if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static", LDNS_RR_CLASS_IN)) || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. " "nobody.invalid. 1 3600 1200 604800 10800") || - !lz_enter_rr_into_zone(z, + !lz_enter_rr_into_zone(z, buf, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) { log_err("out of memory adding default zone"); if(z) { lock_rw_unlock(&z->lock); } @@ -653,109 +670,37 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg) } lock_rw_unlock(&z->lock); } - - /* if unblock lan-zones, then do not add the zones below. - * we do add the zones above, about 127.0.0.1, because localhost is - * not on the lan. */ - if(cfg->unblock_lan_zones) - return 1; - - /* block LAN level zones */ - if ( !add_as112_default(zones, cfg, "10.in-addr.arpa.") || - !add_as112_default(zones, cfg, "16.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "17.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "18.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "19.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "20.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "21.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "22.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "23.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "24.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "25.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "26.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "27.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "28.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "29.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "30.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "31.172.in-addr.arpa.") || - !add_as112_default(zones, cfg, "168.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "0.in-addr.arpa.") || - !add_as112_default(zones, cfg, "64.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "65.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "66.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "67.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "68.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "69.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "70.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "71.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "72.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "73.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "74.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "75.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "76.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "77.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "78.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "79.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "80.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "81.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "82.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "83.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "84.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "85.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "86.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "87.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "88.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "89.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "90.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "91.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "92.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "93.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "94.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "95.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "96.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "97.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "98.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "99.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "101.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "102.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "103.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "104.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "105.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "106.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "107.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "108.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "109.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "110.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "111.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "112.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "114.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "115.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "116.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "117.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "118.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "119.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "120.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "121.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "122.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "123.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "124.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "125.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "126.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "127.100.in-addr.arpa.") || - !add_as112_default(zones, cfg, "254.169.in-addr.arpa.") || - !add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") || - !add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") || - !add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") || - !add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") || - !add_as112_default(zones, cfg, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") || - !add_as112_default(zones, cfg, "d.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) { + if ( !add_as112_default(zones, cfg, buf, "10.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "16.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "17.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "18.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "19.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "20.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "21.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "22.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "23.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "24.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "25.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "26.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "27.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "28.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "29.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "30.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "31.172.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "168.192.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") || + !add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "8.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") || + !add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) { log_err("out of memory adding default zone"); return 0; } @@ -768,7 +713,7 @@ init_parents(struct local_zones* zones) { struct local_zone* node, *prev = NULL, *p; int m; - lock_rw_wrlock(&zones->lock); + lock_quick_lock(&zones->lock); RBTREE_FOR(node, struct local_zone*, &zones->ztree) { lock_rw_wrlock(&node->lock); node->parent = NULL; @@ -793,7 +738,7 @@ init_parents(struct local_zones* zones) prev = node; lock_rw_unlock(&node->lock); } - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); } /** enter implicit transparent zone for local-data: without local-zone: */ @@ -823,7 +768,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) return 0; } labs = dname_count_size_labels(rr_name, &len); - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); if(!local_zones_lookup(zones, rr_name, len, labs, rr_class)) { if(!have_name) { dclass = rr_class; @@ -838,7 +783,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) /* process other classes later */ free(rr_name); have_other_classes = 1; - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); continue; } /* find smallest shared topdomain */ @@ -849,7 +794,7 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) match = m; } } else free(rr_name); - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); } if(have_name) { uint8_t* n2; @@ -880,11 +825,12 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg) /** enter auth data */ static int -lz_enter_data(struct local_zones* zones, struct config_file* cfg) +lz_enter_data(struct local_zones* zones, struct config_file* cfg, + ldns_buffer* buf) { struct config_strlist* p; for(p = cfg->local_data; p; p = p->next) { - if(!lz_enter_rr_str(zones, p->str)) + if(!lz_enter_rr_str(zones, p->str, buf)) return 0; } return 1; @@ -905,27 +851,35 @@ lz_freeup_cfg(struct config_file* cfg) int local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg) { + ldns_buffer* buf = ldns_buffer_new(65535); + if(!buf) fatal_exit("cannot create temporary buffer"); + /* create zones from zone statements. */ if(!lz_enter_zones(zones, cfg)) { + ldns_buffer_free(buf); return 0; } /* apply default zones+content (unless disabled, or overridden) */ - if(!lz_enter_defaults(zones, cfg)) { + if(!lz_enter_defaults(zones, cfg, buf)) { + ldns_buffer_free(buf); return 0; } /* create implicit transparent zone from data. */ if(!lz_setup_implicit(zones, cfg)) { + ldns_buffer_free(buf); return 0; } /* setup parent ptrs for lookup during data entry */ init_parents(zones); /* insert local data */ - if(!lz_enter_data(zones, cfg)) { + if(!lz_enter_data(zones, cfg, buf)) { + ldns_buffer_free(buf); return 0; } /* freeup memory from cfg struct. */ lz_freeup_cfg(cfg); + ldns_buffer_free(buf); return 1; } @@ -994,7 +948,7 @@ local_zone_out(struct local_zone* z) void local_zones_print(struct local_zones* zones) { struct local_zone* z; - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); log_info("number of auth zones %u", (unsigned)zones->ztree.count); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); @@ -1023,14 +977,6 @@ void local_zones_print(struct local_zones* zones) log_nametypeclass(0, "static zone", z->name, 0, z->dclass); break; - case local_zone_inform: - log_nametypeclass(0, "inform zone", - z->name, 0, z->dclass); - break; - case local_zone_inform_deny: - log_nametypeclass(0, "inform_deny zone", - z->name, 0, z->dclass); - break; default: log_nametypeclass(0, "badtyped zone", z->name, 0, z->dclass); @@ -1039,13 +985,13 @@ void local_zones_print(struct local_zones* zones) local_zone_out(z); lock_rw_unlock(&z->lock); } - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); } /** encode answer consisting of 1 rrset */ static int local_encode(struct query_info* qinfo, struct edns_data* edns, - sldns_buffer* buf, struct regional* temp, + ldns_buffer* buf, struct regional* temp, struct ub_packed_rrset_key* rrset, int ansec, int rcode) { struct reply_info rep; @@ -1065,20 +1011,20 @@ local_encode(struct query_info* qinfo, struct edns_data* edns, edns->ext_rcode = 0; edns->bits &= EDNS_DO; if(!reply_info_answer_encode(qinfo, &rep, - *(uint16_t*)sldns_buffer_begin(buf), - sldns_buffer_read_u16_at(buf, 2), + *(uint16_t*)ldns_buffer_begin(buf), + ldns_buffer_read_u16_at(buf, 2), buf, 0, 0, temp, udpsize, edns, (int)(edns->bits&EDNS_DO), 0)) error_encode(buf, (LDNS_RCODE_SERVFAIL|BIT_AA), qinfo, - *(uint16_t*)sldns_buffer_begin(buf), - sldns_buffer_read_u16_at(buf, 2), edns); + *(uint16_t*)ldns_buffer_begin(buf), + ldns_buffer_read_u16_at(buf, 2), edns); return 1; } /** answer local data match */ static int local_data_answer(struct local_zone* z, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, + struct edns_data* edns, ldns_buffer* buf, struct regional* temp, int labs, struct local_data** ldp) { struct local_data key; @@ -1125,18 +1071,18 @@ local_data_answer(struct local_zone* z, struct query_info* qinfo, */ static int lz_zone_answer(struct local_zone* z, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, + struct edns_data* edns, ldns_buffer* buf, struct regional* temp, struct local_data* ld) { - if(z->type == local_zone_deny || z->type == local_zone_inform_deny) { + if(z->type == local_zone_deny) { /** no reply at all, signal caller by clearing buffer. */ - sldns_buffer_clear(buf); - sldns_buffer_flip(buf); + ldns_buffer_clear(buf); + ldns_buffer_flip(buf); return 1; } else if(z->type == local_zone_refuse) { error_encode(buf, (LDNS_RCODE_REFUSED|BIT_AA), qinfo, - *(uint16_t*)sldns_buffer_begin(buf), - sldns_buffer_read_u16_at(buf, 2), edns); + *(uint16_t*)ldns_buffer_begin(buf), + ldns_buffer_read_u16_at(buf, 2), edns); return 1; } else if(z->type == local_zone_static || z->type == local_zone_redirect) { @@ -1152,8 +1098,8 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo, return local_encode(qinfo, edns, buf, temp, z->soa, 0, rcode); error_encode(buf, (rcode|BIT_AA), qinfo, - *(uint16_t*)sldns_buffer_begin(buf), - sldns_buffer_read_u16_at(buf, 2), edns); + *(uint16_t*)ldns_buffer_begin(buf), + ldns_buffer_read_u16_at(buf, 2), edns); return 1; } else if(z->type == local_zone_typetransparent) { /* no NODATA or NXDOMAINS for this zone type */ @@ -1169,8 +1115,8 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo, return local_encode(qinfo, edns, buf, temp, z->soa, 0, rcode); error_encode(buf, (rcode|BIT_AA), qinfo, - *(uint16_t*)sldns_buffer_begin(buf), - sldns_buffer_read_u16_at(buf, 2), edns); + *(uint16_t*)ldns_buffer_begin(buf), + ldns_buffer_read_u16_at(buf, 2), edns); return 1; } @@ -1178,25 +1124,9 @@ lz_zone_answer(struct local_zone* z, struct query_info* qinfo, return 0; } -/** print log information for an inform zone query */ -static void -lz_inform_print(struct local_zone* z, struct query_info* qinfo, - struct comm_reply* repinfo) -{ - char ip[128], txt[512]; - char zname[LDNS_MAX_DOMAINLEN+1]; - uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port); - dname_str(z->name, zname); - addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip)); - snprintf(txt, sizeof(txt), "%s inform %s@%u", zname, ip, - (unsigned)port); - log_nametypeclass(0, txt, qinfo->qname, qinfo->qtype, qinfo->qclass); -} - int local_zones_answer(struct local_zones* zones, struct query_info* qinfo, - struct edns_data* edns, sldns_buffer* buf, struct regional* temp, - struct comm_reply* repinfo) + struct edns_data* edns, ldns_buffer* buf, struct regional* temp) { /* see if query is covered by a zone, * if so: - try to match (exact) local data @@ -1205,19 +1135,15 @@ local_zones_answer(struct local_zones* zones, struct query_info* qinfo, struct local_data* ld; struct local_zone* z; int r; - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); z = local_zones_lookup(zones, qinfo->qname, qinfo->qname_len, labs, qinfo->qclass); if(!z) { - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); return 0; } lock_rw_rdlock(&z->lock); - lock_rw_unlock(&zones->lock); - - if((z->type == local_zone_inform || z->type == local_zone_inform_deny) - && repinfo) - lz_inform_print(z, qinfo, repinfo); + lock_quick_unlock(&zones->lock); if(local_data_answer(z, qinfo, edns, buf, temp, labs, &ld)) { lock_rw_unlock(&z->lock); @@ -1238,8 +1164,6 @@ const char* local_zone_type2str(enum localzone_type t) case local_zone_typetransparent: return "typetransparent"; case local_zone_static: return "static"; case local_zone_nodefault: return "nodefault"; - case local_zone_inform: return "inform"; - case local_zone_inform_deny: return "inform_deny"; } return "badtyped"; } @@ -1258,10 +1182,6 @@ int local_zone_str2type(const char* type, enum localzone_type* t) *t = local_zone_typetransparent; else if(strcmp(type, "redirect") == 0) *t = local_zone_redirect; - else if(strcmp(type, "inform") == 0) - *t = local_zone_inform; - else if(strcmp(type, "inform_deny") == 0) - *t = local_zone_inform_deny; else return 0; return 1; } @@ -1335,7 +1255,7 @@ void local_zones_del_zone(struct local_zones* zones, struct local_zone* z) } int -local_zones_add_RR(struct local_zones* zones, const char* rr) +local_zones_add_RR(struct local_zones* zones, const char* rr, ldns_buffer* buf) { uint8_t* rr_name; uint16_t rr_class; @@ -1347,23 +1267,21 @@ local_zones_add_RR(struct local_zones* zones, const char* rr) return 0; } labs = dname_count_size_labels(rr_name, &len); - /* could first try readlock then get writelock if zone does not exist, - * but we do not add enough RRs (from multiple threads) to optimize */ - lock_rw_wrlock(&zones->lock); + lock_quick_lock(&zones->lock); z = local_zones_lookup(zones, rr_name, len, labs, rr_class); if(!z) { z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, local_zone_transparent); if(!z) { - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); return 0; } } else { free(rr_name); } lock_rw_wrlock(&z->lock); - lock_rw_unlock(&zones->lock); - r = lz_enter_rr_into_zone(z, rr); + lock_quick_unlock(&zones->lock); + r = lz_enter_rr_into_zone(z, buf, rr); lock_rw_unlock(&z->lock); return r; } @@ -1408,15 +1326,15 @@ void local_zones_del_data(struct local_zones* zones, /* find zone */ struct local_zone* z; struct local_data* d; - lock_rw_rdlock(&zones->lock); + lock_quick_lock(&zones->lock); z = local_zones_lookup(zones, name, len, labs, dclass); if(!z) { /* no such zone, we're done */ - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); return; } lock_rw_wrlock(&z->lock); - lock_rw_unlock(&zones->lock); + lock_quick_unlock(&zones->lock); /* find the domain */ d = lz_find_node(z, name, len, labs); diff --git a/usr.sbin/unbound/services/outside_network.c b/usr.sbin/unbound/services/outside_network.c index f105bc0d48b..7fd408e7987 100644 --- a/usr.sbin/unbound/services/outside_network.c +++ b/usr.sbin/unbound/services/outside_network.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -45,6 +45,7 @@ # include <sys/types.h> #endif #include <sys/time.h> +#include <ldns/wire2host.h> #include "services/outside_network.h" #include "services/listen_dnsport.h" #include "services/cache/infra.h" @@ -57,11 +58,7 @@ #include "util/net_help.h" #include "util/random.h" #include "util/fptr_wlist.h" -#include "sldns/sbuffer.h" -#include "dnstap/dnstap.h" -#ifdef HAVE_OPENSSL_SSL_H #include <openssl/ssl.h> -#endif #ifdef HAVE_NETDB_H #include <netdb.h> @@ -76,14 +73,11 @@ #define OUTBOUND_UDP_RETRY 1 /** initiate TCP transaction for serviced query */ -static void serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff); +static void serviced_tcp_initiate(struct outside_network* outnet, + struct serviced_query* sq, ldns_buffer* buff); /** with a fd available, randomize and send UDP */ -static int randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, - int timeout); - -/** remove waiting tcp from the outnet waiting list */ -static void waiting_list_remove(struct outside_network* outnet, - struct waiting_tcp* w); +static int randomize_and_send_udp(struct outside_network* outnet, + struct pending* pend, ldns_buffer* packet, int timeout); int pending_cmp(const void* key1, const void* key2) @@ -214,12 +208,12 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if(s == -1) { #ifndef USE_WINSOCK - log_err_addr("outgoing tcp: socket", strerror(errno), - &w->addr, w->addrlen); + log_err("outgoing tcp: socket: %s", strerror(errno)); #else - log_err_addr("outgoing tcp: socket", - wsa_strerror(WSAGetLastError()), &w->addr, w->addrlen); + log_err("outgoing tcp: socket: %s", + wsa_strerror(WSAGetLastError())); #endif + log_addr(0, "failed address", &w->addr, w->addrlen); return 0; } if(!pick_outgoing_tcp(w, s)) @@ -233,16 +227,14 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) #else if(1) { #endif - if(tcp_connect_errno_needs_log( - (struct sockaddr*)&w->addr, w->addrlen)) - log_err_addr("outgoing tcp: connect", - strerror(errno), &w->addr, w->addrlen); + log_err("outgoing tcp: connect: %s", strerror(errno)); close(s); #else /* USE_WINSOCK */ if(WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) { closesocket(s); #endif + log_addr(0, "failed address", &w->addr, w->addrlen); return 0; } } @@ -261,15 +253,14 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len) w->pkt = NULL; w->next_waiting = (void*)pend; pend->id = LDNS_ID_WIRE(pkt); - w->outnet->num_tcp_outgoing++; w->outnet->tcp_free = pend->next_free; pend->next_free = NULL; pend->query = w; pend->c->repinfo.addrlen = w->addrlen; memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen); - sldns_buffer_clear(pend->c->buffer); - sldns_buffer_write(pend->c->buffer, pkt, pkt_len); - sldns_buffer_flip(pend->c->buffer); + ldns_buffer_clear(pend->c->buffer); + ldns_buffer_write(pend->c->buffer, pkt, pkt_len); + ldns_buffer_flip(pend->c->buffer); pend->c->tcp_is_reading = 0; pend->c->tcp_byte_count = 0; comm_point_start_listening(pend->c, s, -1); @@ -303,11 +294,9 @@ decomission_pending_tcp(struct outside_network* outnet, struct pending_tcp* pend) { if(pend->c->ssl) { -#ifdef HAVE_SSL SSL_shutdown(pend->c->ssl); SSL_free(pend->c->ssl); pend->c->ssl = NULL; -#endif } comm_point_close(pend->c); pend->next_free = outnet->tcp_free; @@ -329,8 +318,8 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error, /* pass error below and exit */ } else { /* check ID */ - if(sldns_buffer_limit(c->buffer) < sizeof(uint16_t) || - LDNS_ID_WIRE(sldns_buffer_begin(c->buffer))!=pend->id) { + if(ldns_buffer_limit(c->buffer) < sizeof(uint16_t) || + LDNS_ID_WIRE(ldns_buffer_begin(c->buffer))!=pend->id) { log_addr(VERB_QUERY, "outnettcp: bad ID in reply, from:", &pend->query->addr, pend->query->addrlen); @@ -376,20 +365,18 @@ outnet_send_wait_udp(struct outside_network* outnet) pend = outnet->udp_wait_first; outnet->udp_wait_first = pend->next_waiting; if(!pend->next_waiting) outnet->udp_wait_last = NULL; - sldns_buffer_clear(outnet->udp_buff); - sldns_buffer_write(outnet->udp_buff, pend->pkt, pend->pkt_len); - sldns_buffer_flip(outnet->udp_buff); + ldns_buffer_clear(outnet->udp_buff); + ldns_buffer_write(outnet->udp_buff, pend->pkt, pend->pkt_len); + ldns_buffer_flip(outnet->udp_buff); free(pend->pkt); /* freeing now makes get_mem correct */ pend->pkt = NULL; pend->pkt_len = 0; - if(!randomize_and_send_udp(pend, outnet->udp_buff, + if(!randomize_and_send_udp(outnet, pend, outnet->udp_buff, pend->timeout)) { /* callback error on pending */ - if(pend->cb) { - fptr_ok(fptr_whitelist_pending_udp(pend->cb)); - (void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg, - NETEVENT_CLOSED, NULL); - } + fptr_ok(fptr_whitelist_pending_udp(pend->cb)); + (void)(*pend->cb)(outnet->unused_fds->cp, pend->cb_arg, + NETEVENT_CLOSED, NULL); pending_delete(outnet, pend); } } @@ -408,14 +395,14 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error, verbose(VERB_QUERY, "outnetudp got udp error %d", error); return 0; } - if(sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) { + if(ldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE) { verbose(VERB_QUERY, "outnetudp udp too short"); return 0; } log_assert(reply_info); /* setup lookup key */ - key.id = (unsigned)LDNS_ID_WIRE(sldns_buffer_begin(c->buffer)); + key.id = (unsigned)LDNS_ID_WIRE(ldns_buffer_begin(c->buffer)); memcpy(&key.addr, &reply_info->addr, reply_info->addrlen); key.addrlen = reply_info->addrlen; verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id); @@ -466,10 +453,8 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error, verbose(VERB_ALGO, "outnet handle udp reply"); /* delete from tree first in case callback creates a retry */ (void)rbtree_delete(outnet->pending, p->node.key); - if(p->cb) { - fptr_ok(fptr_whitelist_pending_udp(p->cb)); - (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info); - } + fptr_ok(fptr_whitelist_pending_udp(p->cb)); + (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_NOERROR, reply_info); portcomm_loweruse(outnet, p->pc); pending_delete(NULL, p); outnet_send_wait_udp(outnet); @@ -504,17 +489,6 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6, } -void -pending_udp_timer_delay_cb(void* arg) -{ - struct pending* p = (struct pending*)arg; - struct outside_network* outnet = p->outnet; - verbose(VERB_ALGO, "timeout udp with delay"); - portcomm_loweruse(outnet, p->pc); - pending_delete(outnet, p); - outnet_send_wait_udp(outnet); -} - void pending_udp_timer_cb(void *arg) { @@ -522,20 +496,8 @@ pending_udp_timer_cb(void *arg) struct outside_network* outnet = p->outnet; /* it timed out */ verbose(VERB_ALGO, "timeout udp"); - if(p->cb) { - fptr_ok(fptr_whitelist_pending_udp(p->cb)); - (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL); - } - /* if delayclose, keep port open for a longer time. - * But if the udpwaitlist exists, then we are struggling to - * keep up with demand for sockets, so do not wait, but service - * the customer (customer service more important than portICMPs) */ - if(outnet->delayclose && !outnet->udp_wait_first) { - p->cb = NULL; - p->timer->callback = &pending_udp_timer_delay_cb; - comm_timer_set(p->timer, &outnet->delay_tv); - return; - } + fptr_ok(fptr_whitelist_pending_udp(p->cb)); + (void)(*p->cb)(p->pc->cp, p->cb_arg, NETEVENT_TIMEOUT, NULL); portcomm_loweruse(outnet, p->pc); pending_delete(outnet, p); outnet_send_wait_udp(outnet); @@ -592,7 +554,7 @@ outside_network_create(struct comm_base *base, size_t bufsize, struct ub_randstate* rnd, int use_caps_for_id, int* availports, int numavailports, size_t unwanted_threshold, void (*unwanted_action)(void*), void* unwanted_param, int do_udp, - void* sslctx, int delayclose, struct dt_env* dtenv) + void* sslctx) { struct outside_network* outnet = (struct outside_network*) calloc(1, sizeof(struct outside_network)); @@ -604,15 +566,9 @@ outside_network_create(struct comm_base *base, size_t bufsize, comm_base_timept(base, &outnet->now_secs, &outnet->now_tv); outnet->base = base; outnet->num_tcp = num_tcp; - outnet->num_tcp_outgoing = 0; outnet->infra = infra; outnet->rnd = rnd; outnet->sslctx = sslctx; -#ifdef USE_DNSTAP - outnet->dtenv = dtenv; -#else - (void)dtenv; -#endif outnet->svcd_overhead = 0; outnet->want_to_quit = 0; outnet->unwanted_threshold = unwanted_threshold; @@ -620,13 +576,6 @@ outside_network_create(struct comm_base *base, size_t bufsize, outnet->unwanted_param = unwanted_param; outnet->use_caps_for_id = use_caps_for_id; outnet->do_udp = do_udp; -#ifndef S_SPLINT_S - if(delayclose) { - outnet->delayclose = 1; - outnet->delay_tv.tv_sec = delayclose/1000; - outnet->delay_tv.tv_usec = (delayclose%1000)*1000; - } -#endif if(numavailports == 0) { log_err("no outgoing ports available"); outside_network_delete(outnet); @@ -653,7 +602,7 @@ outside_network_create(struct comm_base *base, size_t bufsize, return NULL; } } - if( !(outnet->udp_buff = sldns_buffer_new(bufsize)) || + if( !(outnet->udp_buff = ldns_buffer_new(bufsize)) || !(outnet->pending = rbtree_create(pending_cmp)) || !(outnet->serviced = rbtree_create(serviced_cmp)) || !create_pending_tcp(outnet, bufsize)) { @@ -775,7 +724,7 @@ outside_network_delete(struct outside_network* outnet) free(outnet->serviced); } if(outnet->udp_buff) - sldns_buffer_free(outnet->udp_buff); + ldns_buffer_free(outnet->udp_buff); if(outnet->unused_fds) { struct port_comm* p = outnet->unused_fds, *np; while(p) { @@ -893,13 +842,13 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port, sa->sin6_port = (in_port_t)htons((uint16_t)port); fd = create_udp_sock(AF_INET6, SOCK_DGRAM, (struct sockaddr*)addr, addrlen, 1, inuse, &noproto, - 0, 0, 0, NULL, 0); + 0, 0); } else { struct sockaddr_in* sa = (struct sockaddr_in*)addr; sa->sin_port = (in_port_t)htons((uint16_t)port); fd = create_udp_sock(AF_INET, SOCK_DGRAM, (struct sockaddr*)addr, addrlen, 1, inuse, &noproto, - 0, 0, 0, NULL, 0); + 0, 0); } return fd; } @@ -907,18 +856,18 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port, /** Select random ID */ static int select_id(struct outside_network* outnet, struct pending* pend, - sldns_buffer* packet) + ldns_buffer* packet) { int id_tries = 0; pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff; - LDNS_ID_SET(sldns_buffer_begin(packet), pend->id); + LDNS_ID_SET(ldns_buffer_begin(packet), pend->id); /* insert in tree */ pend->node.key = pend; while(!rbtree_insert(outnet->pending, &pend->node)) { /* change ID to avoid collision */ pend->id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff; - LDNS_ID_SET(sldns_buffer_begin(packet), pend->id); + LDNS_ID_SET(ldns_buffer_begin(packet), pend->id); id_tries++; if(id_tries == MAX_ID_RETRY) { pend->id=99999; /* non existant ID */ @@ -1001,10 +950,10 @@ select_ifport(struct outside_network* outnet, struct pending* pend, } static int -randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout) +randomize_and_send_udp(struct outside_network* outnet, struct pending* pend, + ldns_buffer* packet, int timeout) { struct timeval tv; - struct outside_network* outnet = pend->sq->outnet; /* select id */ if(!select_id(outnet, pend, packet)) { @@ -1037,43 +986,35 @@ randomize_and_send_udp(struct pending* pend, sldns_buffer* packet, int timeout) tv.tv_usec = (timeout%1000)*1000; #endif comm_timer_set(pend->timer, &tv); - -#ifdef USE_DNSTAP - if(outnet->dtenv && - (outnet->dtenv->log_resolver_query_messages || - outnet->dtenv->log_forwarder_query_messages)) - dt_msg_send_outside_query(outnet->dtenv, &pend->addr, comm_udp, - pend->sq->zone, pend->sq->zonelen, packet); -#endif return 1; } struct pending* -pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet, - int timeout, comm_point_callback_t* cb, void* cb_arg) +pending_udp_query(struct outside_network* outnet, ldns_buffer* packet, + struct sockaddr_storage* addr, socklen_t addrlen, int timeout, + comm_point_callback_t* cb, void* cb_arg) { struct pending* pend = (struct pending*)calloc(1, sizeof(*pend)); if(!pend) return NULL; - pend->outnet = sq->outnet; - pend->sq = sq; - pend->addrlen = sq->addrlen; - memmove(&pend->addr, &sq->addr, sq->addrlen); + pend->outnet = outnet; + pend->addrlen = addrlen; + memmove(&pend->addr, addr, addrlen); pend->cb = cb; pend->cb_arg = cb_arg; pend->node.key = pend; - pend->timer = comm_timer_create(sq->outnet->base, pending_udp_timer_cb, + pend->timer = comm_timer_create(outnet->base, pending_udp_timer_cb, pend); if(!pend->timer) { free(pend); return NULL; } - if(sq->outnet->unused_fds == NULL) { + if(outnet->unused_fds == NULL) { /* no unused fd, cannot create a new port (randomly) */ verbose(VERB_ALGO, "no fds available, udp query waiting"); pend->timeout = timeout; - pend->pkt_len = sldns_buffer_limit(packet); - pend->pkt = (uint8_t*)memdup(sldns_buffer_begin(packet), + pend->pkt_len = ldns_buffer_limit(packet); + pend->pkt = (uint8_t*)memdup(ldns_buffer_begin(packet), pend->pkt_len); if(!pend->pkt) { comm_timer_delete(pend->timer); @@ -1081,15 +1022,15 @@ pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet, return NULL; } /* put at end of waiting list */ - if(sq->outnet->udp_wait_last) - sq->outnet->udp_wait_last->next_waiting = pend; + if(outnet->udp_wait_last) + outnet->udp_wait_last->next_waiting = pend; else - sq->outnet->udp_wait_first = pend; - sq->outnet->udp_wait_last = pend; + outnet->udp_wait_first = pend; + outnet->udp_wait_last = pend; return pend; } - if(!randomize_and_send_udp(pend, packet, timeout)) { - pending_delete(sq->outnet, pend); + if(!randomize_and_send_udp(outnet, pend, packet, timeout)) { + pending_delete(outnet, pend); return NULL; } return pend; @@ -1104,7 +1045,17 @@ outnet_tcptimer(void* arg) void* cb_arg; if(w->pkt) { /* it is on the waiting list */ - waiting_list_remove(outnet, w); + struct waiting_tcp* p=outnet->tcp_wait_first, *prev=NULL; + while(p) { + if(p == w) { + if(prev) prev->next_waiting = w->next_waiting; + else outnet->tcp_wait_first=w->next_waiting; + outnet->tcp_wait_last = prev; + break; + } + prev = p; + p=p->next_waiting; + } } else { /* it was in use */ struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting; @@ -1121,34 +1072,35 @@ outnet_tcptimer(void* arg) use_free_buffer(outnet); } -struct waiting_tcp* -pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet, - int timeout, comm_point_callback_t* callback, void* callback_arg) +struct waiting_tcp* +pending_tcp_query(struct outside_network* outnet, ldns_buffer* packet, + struct sockaddr_storage* addr, socklen_t addrlen, int timeout, + comm_point_callback_t* callback, void* callback_arg, int ssl_upstream) { - struct pending_tcp* pend = sq->outnet->tcp_free; + struct pending_tcp* pend = outnet->tcp_free; struct waiting_tcp* w; struct timeval tv; uint16_t id; /* if no buffer is free allocate space to store query */ w = (struct waiting_tcp*)malloc(sizeof(struct waiting_tcp) - + (pend?0:sldns_buffer_limit(packet))); + + (pend?0:ldns_buffer_limit(packet))); if(!w) { return NULL; } - if(!(w->timer = comm_timer_create(sq->outnet->base, outnet_tcptimer, w))) { + if(!(w->timer = comm_timer_create(outnet->base, outnet_tcptimer, w))) { free(w); return NULL; } w->pkt = NULL; w->pkt_len = 0; - id = ((unsigned)ub_random(sq->outnet->rnd)>>8) & 0xffff; - LDNS_ID_SET(sldns_buffer_begin(packet), id); - memcpy(&w->addr, &sq->addr, sq->addrlen); - w->addrlen = sq->addrlen; - w->outnet = sq->outnet; + id = ((unsigned)ub_random(outnet->rnd)>>8) & 0xffff; + LDNS_ID_SET(ldns_buffer_begin(packet), id); + memcpy(&w->addr, addr, addrlen); + w->addrlen = addrlen; + w->outnet = outnet; w->cb = callback; w->cb_arg = callback_arg; - w->ssl_upstream = sq->ssl_upstream; + w->ssl_upstream = ssl_upstream; #ifndef S_SPLINT_S tv.tv_sec = timeout; tv.tv_usec = 0; @@ -1156,59 +1108,52 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet, comm_timer_set(w->timer, &tv); if(pend) { /* we have a buffer available right now */ - if(!outnet_tcp_take_into_use(w, sldns_buffer_begin(packet), - sldns_buffer_limit(packet))) { + if(!outnet_tcp_take_into_use(w, ldns_buffer_begin(packet), + ldns_buffer_limit(packet))) { waiting_tcp_delete(w); return NULL; } -#ifdef USE_DNSTAP - if(sq->outnet->dtenv && - (sq->outnet->dtenv->log_resolver_query_messages || - sq->outnet->dtenv->log_forwarder_query_messages)) - dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr, - comm_tcp, sq->zone, sq->zonelen, packet); -#endif } else { /* queue up */ w->pkt = (uint8_t*)w + sizeof(struct waiting_tcp); - w->pkt_len = sldns_buffer_limit(packet); - memmove(w->pkt, sldns_buffer_begin(packet), w->pkt_len); + w->pkt_len = ldns_buffer_limit(packet); + memmove(w->pkt, ldns_buffer_begin(packet), w->pkt_len); w->next_waiting = NULL; - if(sq->outnet->tcp_wait_last) - sq->outnet->tcp_wait_last->next_waiting = w; - else sq->outnet->tcp_wait_first = w; - sq->outnet->tcp_wait_last = w; + if(outnet->tcp_wait_last) + outnet->tcp_wait_last->next_waiting = w; + else outnet->tcp_wait_first = w; + outnet->tcp_wait_last = w; } return w; } /** create query for serviced queries */ static void -serviced_gen_query(sldns_buffer* buff, uint8_t* qname, size_t qnamelen, +serviced_gen_query(ldns_buffer* buff, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags) { - sldns_buffer_clear(buff); + ldns_buffer_clear(buff); /* skip id */ - sldns_buffer_write_u16(buff, flags); - sldns_buffer_write_u16(buff, 1); /* qdcount */ - sldns_buffer_write_u16(buff, 0); /* ancount */ - sldns_buffer_write_u16(buff, 0); /* nscount */ - sldns_buffer_write_u16(buff, 0); /* arcount */ - sldns_buffer_write(buff, qname, qnamelen); - sldns_buffer_write_u16(buff, qtype); - sldns_buffer_write_u16(buff, qclass); - sldns_buffer_flip(buff); + ldns_buffer_write_u16(buff, flags); + ldns_buffer_write_u16(buff, 1); /* qdcount */ + ldns_buffer_write_u16(buff, 0); /* ancount */ + ldns_buffer_write_u16(buff, 0); /* nscount */ + ldns_buffer_write_u16(buff, 0); /* arcount */ + ldns_buffer_write(buff, qname, qnamelen); + ldns_buffer_write_u16(buff, qtype); + ldns_buffer_write_u16(buff, qclass); + ldns_buffer_flip(buff); } /** lookup serviced query in serviced query rbtree */ static struct serviced_query* -lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec, +lookup_serviced(struct outside_network* outnet, ldns_buffer* buff, int dnssec, struct sockaddr_storage* addr, socklen_t addrlen) { struct serviced_query key; key.node.key = &key; - key.qbuf = sldns_buffer_begin(buff); - key.qbuflen = sldns_buffer_limit(buff); + key.qbuf = ldns_buffer_begin(buff); + key.qbuflen = ldns_buffer_limit(buff); key.dnssec = dnssec; memcpy(&key.addr, addr, addrlen); key.addrlen = addrlen; @@ -1218,10 +1163,10 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec, /** Create new serviced entry */ static struct serviced_query* -serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec, - int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream, +serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec, + int want_dnssec, int tcp_upstream, int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, - size_t zonelen, int qtype) + size_t zonelen) { struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq)); #ifdef UNBOUND_DEBUG @@ -1230,12 +1175,12 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec, if(!sq) return NULL; sq->node.key = sq; - sq->qbuf = memdup(sldns_buffer_begin(buff), sldns_buffer_limit(buff)); + sq->qbuf = memdup(ldns_buffer_begin(buff), ldns_buffer_limit(buff)); if(!sq->qbuf) { free(sq); return NULL; } - sq->qbuflen = sldns_buffer_limit(buff); + sq->qbuflen = ldns_buffer_limit(buff); sq->zone = memdup(zone, zonelen); if(!sq->zone) { free(sq->qbuf); @@ -1243,10 +1188,8 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec, return NULL; } sq->zonelen = zonelen; - sq->qtype = qtype; sq->dnssec = dnssec; sq->want_dnssec = want_dnssec; - sq->nocaps = nocaps; sq->tcp_upstream = tcp_upstream; sq->ssl_upstream = ssl_upstream; memcpy(&sq->addr, addr, addrlen); @@ -1259,8 +1202,6 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec, sq->to_be_deleted = 0; #ifdef UNBOUND_DEBUG ins = -#else - (void) #endif rbtree_insert(outnet->serviced, &sq->node); log_assert(ins != NULL); /* must not be already present */ @@ -1334,16 +1275,16 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len) while(lablen) { while(lablen--) { /* only perturb A-Z, a-z */ - if(isalpha((unsigned char)*d)) { + if(isalpha((int)*d)) { /* get a random bit */ if(bits == 0) { random = ub_random(rnd); bits = 30; } if(random & 0x1) { - *d = (uint8_t)toupper((unsigned char)*d); + *d = (uint8_t)toupper((int)*d); } else { - *d = (uint8_t)tolower((unsigned char)*d); + *d = (uint8_t)tolower((int)*d); } random >>= 1; bits--; @@ -1361,17 +1302,17 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len) /** put serviced query into a buffer */ static void -serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns) +serviced_encode(struct serviced_query* sq, ldns_buffer* buff, int with_edns) { /* if we are using 0x20 bits for ID randomness, perturb them */ - if(sq->outnet->use_caps_for_id && !sq->nocaps) { + if(sq->outnet->use_caps_for_id) { serviced_perturb_qname(sq->outnet->rnd, sq->qbuf, sq->qbuflen); } /* generate query */ - sldns_buffer_clear(buff); - sldns_buffer_write_u16(buff, 0); /* id placeholder */ - sldns_buffer_write(buff, sq->qbuf, sq->qbuflen); - sldns_buffer_flip(buff); + ldns_buffer_clear(buff); + ldns_buffer_write_u16(buff, 0); /* id placeholder */ + ldns_buffer_write(buff, sq->qbuf, sq->qbuflen); + ldns_buffer_flip(buff); if(with_edns) { /* add edns section */ struct edns_data edns; @@ -1395,7 +1336,7 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns) if(sq->dnssec & EDNS_DO) edns.bits = EDNS_DO; if(sq->dnssec & BIT_CD) - LDNS_CD_SET(sldns_buffer_begin(buff)); + LDNS_CD_SET(ldns_buffer_begin(buff)); attach_edns_record(buff, &edns); } } @@ -1408,11 +1349,11 @@ serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns) * @return 0 on error. */ static int -serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff) +serviced_udp_send(struct serviced_query* sq, ldns_buffer* buff) { int rtt, vs; uint8_t edns_lame_known; - time_t now = *sq->outnet->now_secs; + uint32_t now = *sq->outnet->now_secs; if(!infra_host(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone, sq->zonelen, now, &vs, &edns_lame_known, &rtt)) @@ -1439,8 +1380,8 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff) sq->last_sent_time = *sq->outnet->now_tv; sq->edns_lame_known = (int)edns_lame_known; verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt); - sq->pending = pending_udp_query(sq, buff, rtt, - serviced_udp_callback, sq); + sq->pending = pending_udp_query(sq->outnet, buff, &sq->addr, + sq->addrlen, rtt, serviced_udp_callback, sq); if(!sq->pending) return 0; return 1; @@ -1448,21 +1389,21 @@ serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff) /** check that perturbed qname is identical */ static int -serviced_check_qname(sldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen) +serviced_check_qname(ldns_buffer* pkt, uint8_t* qbuf, size_t qbuflen) { - uint8_t* d1 = sldns_buffer_at(pkt, 12); + uint8_t* d1 = ldns_buffer_at(pkt, 12); uint8_t* d2 = qbuf+10; uint8_t len1, len2; int count = 0; log_assert(qbuflen >= 15 /* 10 header, root, type, class */); len1 = *d1++; len2 = *d2++; - if(sldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */ + if(ldns_buffer_limit(pkt) < 12+1+4) /* packet too small for qname */ return 0; while(len1 != 0 || len2 != 0) { if(LABEL_IS_PTR(len1)) { - d1 = sldns_buffer_at(pkt, PTR_OFFSET(len1, *d1)); - if(d1 >= sldns_buffer_at(pkt, sldns_buffer_limit(pkt))) + d1 = ldns_buffer_at(pkt, PTR_OFFSET(len1, *d1)); + if(d1 >= ldns_buffer_at(pkt, ldns_buffer_limit(pkt))) return 0; len1 = *d1++; if(count++ > MAX_COMPRESS_PTRS) @@ -1494,14 +1435,12 @@ static void serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, struct comm_reply* rep) { - struct service_callback* p; + struct service_callback* p = sq->cblist, *n; int dobackup = (sq->cblist && sq->cblist->next); /* >1 cb*/ uint8_t *backup_p = NULL; size_t backlen = 0; #ifdef UNBOUND_DEBUG rbnode_t* rem = -#else - (void) #endif /* remove from tree, and schedule for deletion, so that callbacks * can safely deregister themselves and even create new serviced @@ -1510,13 +1449,12 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, log_assert(rem); /* should have been present */ sq->to_be_deleted = 1; verbose(VERB_ALGO, "svcd callbacks start"); - if(sq->outnet->use_caps_for_id && error == NETEVENT_NOERROR && c && - !sq->nocaps) { + if(sq->outnet->use_caps_for_id && error == NETEVENT_NOERROR && c) { /* noerror and nxdomain must have a qname in reply */ - if(sldns_buffer_read_u16_at(c->buffer, 4) == 0 && - (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) + if(ldns_buffer_read_u16_at(c->buffer, 4) == 0 && + (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || - LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) + LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NXDOMAIN)) { verbose(VERB_DETAIL, "no qname in reply to check 0x20ID"); log_addr(VERB_DETAIL, "from server", @@ -1524,7 +1462,7 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, log_buf(VERB_DETAIL, "for packet", c->buffer); error = NETEVENT_CLOSED; c = NULL; - } else if(sldns_buffer_read_u16_at(c->buffer, 4) > 0 && + } else if(ldns_buffer_read_u16_at(c->buffer, 4) > 0 && !serviced_check_qname(c->buffer, sq->qbuf, sq->qbuflen)) { verbose(VERB_DETAIL, "wrong 0x20-ID in reply qname"); @@ -1534,12 +1472,12 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, error = NETEVENT_CAPSFAIL; /* and cleanup too */ pkt_dname_tolower(c->buffer, - sldns_buffer_at(c->buffer, 12)); + ldns_buffer_at(c->buffer, 12)); } else { verbose(VERB_ALGO, "good 0x20-ID in reply qname"); /* cleanup caps, prettier cache contents. */ pkt_dname_tolower(c->buffer, - sldns_buffer_at(c->buffer, 12)); + ldns_buffer_at(c->buffer, 12)); } } if(dobackup && c) { @@ -1547,8 +1485,8 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, * may send outgoing queries that overwrite the buffer. * use secondary buffer to store the query. * This is a data copy, but faster than packet to server */ - backlen = sldns_buffer_limit(c->buffer); - backup_p = memdup(sldns_buffer_begin(c->buffer), backlen); + backlen = ldns_buffer_limit(c->buffer); + backup_p = memdup(ldns_buffer_begin(c->buffer), backlen); if(!backup_p) { log_err("malloc failure in serviced query callbacks"); error = NETEVENT_CLOSED; @@ -1556,17 +1494,16 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, } sq->outnet->svcd_overhead = backlen; } - /* test the actual sq->cblist, because the next elem could be deleted*/ - while((p=sq->cblist) != NULL) { - sq->cblist = p->next; /* remove this element */ + while(p) { + n = p->next; if(dobackup && c) { - sldns_buffer_clear(c->buffer); - sldns_buffer_write(c->buffer, backup_p, backlen); - sldns_buffer_flip(c->buffer); + ldns_buffer_clear(c->buffer); + ldns_buffer_write(c->buffer, backup_p, backlen); + ldns_buffer_flip(c->buffer); } fptr_ok(fptr_whitelist_serviced_query(p->cb)); (void)(*p->cb)(c, p->cb_arg, error, rep); - free(p); + p = n; } if(backup_p) { free(backup_p); @@ -1590,28 +1527,20 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, if(error==NETEVENT_NOERROR) infra_update_tcp_works(sq->outnet->infra, &sq->addr, sq->addrlen, sq->zone, sq->zonelen); -#ifdef USE_DNSTAP - if(error==NETEVENT_NOERROR && sq->outnet->dtenv && - (sq->outnet->dtenv->log_resolver_response_messages || - sq->outnet->dtenv->log_forwarder_response_messages)) - dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr, - c->type, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, - &sq->last_sent_time, sq->outnet->now_tv, c->buffer); -#endif if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS && - (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == - LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(sldns_buffer_begin( + (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == + LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE(ldns_buffer_begin( c->buffer)) == LDNS_RCODE_NOTIMPL) ) { /* attempt to fallback to nonEDNS */ sq->status = serviced_query_TCP_EDNS_fallback; - serviced_tcp_initiate(sq, c->buffer); + serviced_tcp_initiate(sq->outnet, sq, c->buffer); return 0; } else if(error==NETEVENT_NOERROR && sq->status == serviced_query_TCP_EDNS_fallback && - (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == + (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || LDNS_RCODE_WIRE( - sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NXDOMAIN - || LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) + ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NXDOMAIN + || LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_YXDOMAIN)) { /* the fallback produced a result that looks promising, note * that this server should be approached without EDNS */ @@ -1629,7 +1558,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, (now.tv_sec == sq->last_sent_time.tv_sec && now.tv_usec > sq->last_sent_time.tv_usec)) { /* convert from microseconds to milliseconds */ - int roundtime = ((int)(now.tv_sec - sq->last_sent_time.tv_sec))*1000 + int roundtime = ((int)now.tv_sec - (int)sq->last_sent_time.tv_sec)*1000 + ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000; verbose(VERB_ALGO, "measured TCP-time at %d msec", roundtime); log_assert(roundtime >= 0); @@ -1637,8 +1566,8 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, * huge due to system-hibernated and we woke up */ if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) { if(!infra_rtt_update(sq->outnet->infra, &sq->addr, - sq->addrlen, sq->zone, sq->zonelen, sq->qtype, - roundtime, sq->last_rtt, (time_t)now.tv_sec)) + sq->addrlen, sq->zone, sq->zonelen, roundtime, + sq->last_rtt, (uint32_t)now.tv_sec)) log_err("out of memory noting rtt."); } } @@ -1656,14 +1585,16 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error, } static void -serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff) +serviced_tcp_initiate(struct outside_network* outnet, + struct serviced_query* sq, ldns_buffer* buff) { verbose(VERB_ALGO, "initiate TCP query %s", sq->status==serviced_query_TCP_EDNS?"EDNS":""); serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS); sq->last_sent_time = *sq->outnet->now_tv; - sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT, - serviced_tcp_callback, sq); + sq->pending = pending_tcp_query(outnet, buff, &sq->addr, + sq->addrlen, TCP_AUTH_QUERY_TIMEOUT, serviced_tcp_callback, + sq, sq->ssl_upstream); if(!sq->pending) { /* delete from tree so that a retry by above layer does not * clash with this entry */ @@ -1674,7 +1605,7 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff) /** Send serviced query over TCP return false on initial failure */ static int -serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff) +serviced_tcp_send(struct serviced_query* sq, ldns_buffer* buff) { int vs, rtt; uint8_t edns_lame_known; @@ -1687,8 +1618,9 @@ serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff) else sq->status = serviced_query_TCP; serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS); sq->last_sent_time = *sq->outnet->now_tv; - sq->pending = pending_tcp_query(sq, buff, TCP_AUTH_QUERY_TIMEOUT, - serviced_tcp_callback, sq); + sq->pending = pending_tcp_query(sq->outnet, buff, &sq->addr, + sq->addrlen, TCP_AUTH_QUERY_TIMEOUT, serviced_tcp_callback, + sq, sq->ssl_upstream); return sq->pending != NULL; } @@ -1726,8 +1658,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, } sq->retry++; if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, - sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt, - (time_t)now.tv_sec))) + sq->zone, sq->zonelen, -1, sq->last_rtt, + (uint32_t)now.tv_sec))) log_err("out of memory in UDP exponential backoff"); if(sq->retry < OUTBOUND_UDP_RETRY) { log_name_addr(VERB_ALGO, "retry query", sq->qbuf+10, @@ -1749,20 +1681,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, serviced_callbacks(sq, error, c, rep); return 0; } -#ifdef USE_DNSTAP - if(outnet->dtenv && - (outnet->dtenv->log_resolver_response_messages || - outnet->dtenv->log_forwarder_response_messages)) - dt_msg_send_outside_response(outnet->dtenv, &sq->addr, c->type, - sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, - &sq->last_sent_time, sq->outnet->now_tv, c->buffer); -#endif if(!fallback_tcp) { if( (sq->status == serviced_query_UDP_EDNS ||sq->status == serviced_query_UDP_EDNS_FRAG) - && (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) + && (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE( - sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) { + ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) { /* try to get an answer by falling back without EDNS */ verbose(VERB_ALGO, "serviced query: attempt without EDNS"); sq->status = serviced_query_UDP_EDNS_fallback; @@ -1779,7 +1703,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, /* only store noEDNS in cache if domain is noDNSSEC */ if(!sq->want_dnssec) if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) { + sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) { log_err("Out of memory caching no edns for host"); } sq->status = serviced_query_UDP; @@ -1789,15 +1713,15 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "serviced query: EDNS works for", &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - sq->zone, sq->zonelen, 0, (time_t)now.tv_sec)) { + sq->zone, sq->zonelen, 0, (uint32_t)now.tv_sec)) { log_err("Out of memory caching edns works"); } sq->edns_lame_known = 1; } else if(sq->status == serviced_query_UDP_EDNS_fallback && !sq->edns_lame_known && (LDNS_RCODE_WIRE( - sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || - LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == - LDNS_RCODE_NXDOMAIN || LDNS_RCODE_WIRE(sldns_buffer_begin( + ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || + LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) == + LDNS_RCODE_NXDOMAIN || LDNS_RCODE_WIRE(ldns_buffer_begin( c->buffer)) == LDNS_RCODE_YXDOMAIN)) { /* the fallback produced a result that looks promising, note * that this server should be approached without EDNS */ @@ -1806,7 +1730,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_addr(VERB_ALGO, "serviced query: EDNS fails for", &sq->addr, sq->addrlen); if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen, - sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) { + sq->zone, sq->zonelen, -1, (uint32_t)now.tv_sec)) { log_err("Out of memory caching no edns for host"); } } else { @@ -1820,7 +1744,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, (now.tv_sec == sq->last_sent_time.tv_sec && now.tv_usec > sq->last_sent_time.tv_usec)) { /* convert from microseconds to milliseconds */ - int roundtime = ((int)(now.tv_sec - sq->last_sent_time.tv_sec))*1000 + int roundtime = ((int)now.tv_sec - (int)sq->last_sent_time.tv_sec)*1000 + ((int)now.tv_usec - (int)sq->last_sent_time.tv_usec)/1000; verbose(VERB_ALGO, "measured roundtrip at %d msec", roundtime); log_assert(roundtime >= 0); @@ -1828,15 +1752,15 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, * above this value gives trouble with server selection */ if(roundtime < 60000) { if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, - sq->zone, sq->zonelen, sq->qtype, roundtime, - sq->last_rtt, (time_t)now.tv_sec)) + sq->zone, sq->zonelen, roundtime, sq->last_rtt, + (uint32_t)now.tv_sec)) log_err("out of memory noting rtt."); } } } /* end of if_!fallback_tcp */ /* perform TC flag check and TCP fallback after updating our * cache entries for EDNS status and RTT times */ - if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) { + if(LDNS_TC_WIRE(ldns_buffer_begin(c->buffer)) || fallback_tcp) { /* fallback to TCP */ /* this discards partial UDP contents */ if(sq->status == serviced_query_UDP_EDNS || @@ -1845,7 +1769,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, /* if we have unfinished EDNS_fallback, start again */ sq->status = serviced_query_TCP_EDNS; else sq->status = serviced_query_TCP; - serviced_tcp_initiate(sq, c->buffer); + serviced_tcp_initiate(outnet, sq, c->buffer); return 0; } /* yay! an answer */ @@ -1853,29 +1777,44 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, return 0; } +/** find callback in list */ +static struct service_callback* +callback_list_find(struct serviced_query* sq, void* cb_arg, + int (*arg_compare)(void*,void*)) +{ + struct service_callback* p; + for(p = sq->cblist; p; p = p->next) { + if(arg_compare(p->cb_arg, cb_arg)) + return p; + } + return NULL; +} + struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - uint16_t flags, int dnssec, int want_dnssec, int nocaps, - int tcp_upstream, int ssl_upstream, struct sockaddr_storage* addr, - socklen_t addrlen, uint8_t* zone, size_t zonelen, - comm_point_callback_t* callback, void* callback_arg, - sldns_buffer* buff) + uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream, + int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen, + uint8_t* zone, size_t zonelen, comm_point_callback_t* callback, + void* callback_arg, ldns_buffer* buff, int (*arg_compare)(void*,void*)) { struct serviced_query* sq; struct service_callback* cb; serviced_gen_query(buff, qname, qnamelen, qtype, qclass, flags); sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen); - /* duplicate entries are included in the callback list, because - * there is a counterpart registration by our caller that needs to - * be doubly-removed (with callbacks perhaps). */ + if(sq) { + /* see if it is a duplicate notification request for cb_arg */ + if(callback_list_find(sq, callback_arg, arg_compare)) { + return sq; + } + } if(!(cb = (struct service_callback*)malloc(sizeof(*cb)))) return NULL; if(!sq) { /* make new serviced query entry */ - sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps, + sq = serviced_create(outnet, buff, dnssec, want_dnssec, tcp_upstream, ssl_upstream, addr, addrlen, zone, - zonelen, (int)qtype); + zonelen); if(!sq) { free(cb); return NULL; @@ -1934,8 +1873,6 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg) if(!sq->cblist && !sq->to_be_deleted) { #ifdef UNBOUND_DEBUG rbnode_t* rem = -#else - (void) #endif rbtree_delete(sq->outnet->serviced, sq); log_assert(rem); /* should be present */ @@ -1989,7 +1926,7 @@ size_t outnet_get_mem(struct outside_network* outnet) struct port_comm* pc; size_t s = sizeof(*outnet) + sizeof(*outnet->base) + sizeof(*outnet->udp_buff) + - sldns_buffer_capacity(outnet->udp_buff); + ldns_buffer_capacity(outnet->udp_buff); /* second buffer is not ours */ for(pc = outnet->unused_fds; pc; pc = pc->next) { s += sizeof(*pc) + comm_point_get_mem(pc->cp); diff --git a/usr.sbin/unbound/services/outside_network.h b/usr.sbin/unbound/services/outside_network.h index 9959676d33f..bfaab459e40 100644 --- a/usr.sbin/unbound/services/outside_network.h +++ b/usr.sbin/unbound/services/outside_network.h @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -45,7 +45,6 @@ #include "util/rbtree.h" #include "util/netevent.h" -#include "dnstap/dnstap_config.h" struct pending; struct pending_timeout; struct ub_randstate; @@ -55,9 +54,6 @@ struct waiting_udp; struct infra_cache; struct port_comm; struct port_if; -struct sldns_buffer; -struct serviced_query; -struct dt_env; /** * Send queries to outside servers and wait for answers from servers. @@ -67,13 +63,13 @@ struct outside_network { /** Base for select calls */ struct comm_base* base; /** pointer to time in seconds */ - time_t* now_secs; + uint32_t* now_secs; /** pointer to time in microseconds */ struct timeval* now_tv; /** buffer shared by UDP connections, since there is only one datagram at any time. */ - struct sldns_buffer* udp_buff; + ldns_buffer* udp_buff; /** serviced_callbacks malloc overhead when processing multiple * identical serviced queries to the same server. */ size_t svcd_overhead; @@ -98,10 +94,6 @@ struct outside_network { struct port_comm* unused_fds; /** if udp is done */ int do_udp; - /** if udp is delay-closed (delayed answers do not meet closed port)*/ - int delayclose; - /** timeout for delayclose */ - struct timeval delay_tv; /** array of outgoing IP4 interfaces */ struct port_if* ip4_ifs; @@ -128,10 +120,6 @@ struct outside_network { struct ub_randstate* rnd; /** ssl context to create ssl wrapped TCP with DNS connections */ void* sslctx; -#ifdef USE_DNSTAP - /** dnstap environment */ - struct dt_env* dtenv; -#endif /** * Array of tcp pending used for outgoing TCP connections. @@ -142,8 +130,6 @@ struct outside_network { struct pending_tcp **tcp_conns; /** number of tcp communication points. */ size_t num_tcp; - /** number of tcp communication points in use. */ - size_t num_tcp_outgoing; /** list of tcp comm points that are free for use */ struct pending_tcp* tcp_free; /** list of tcp queries waiting for a buffer */ @@ -219,8 +205,6 @@ struct pending { void* cb_arg; /** the outside network it is part of */ struct outside_network* outnet; - /** the corresponding serviced_query */ - struct serviced_query* sq; /*---- filled if udp pending is waiting -----*/ /** next in waiting list. */ @@ -295,9 +279,9 @@ struct service_callback { }; /** fallback size for fragmentation for EDNS in IPv4 */ -#define EDNS_FRAG_SIZE_IP4 1472 +#define EDNS_FRAG_SIZE_IP4 1480 /** fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids */ -#define EDNS_FRAG_SIZE_IP6 1232 +#define EDNS_FRAG_SIZE_IP6 1260 /** * Query service record. @@ -318,8 +302,6 @@ struct serviced_query { int dnssec; /** We want signatures, or else the answer is likely useless */ int want_dnssec; - /** ignore capsforid */ - int nocaps; /** tcp upstream used, use tcp, or ssl_upstream for SSL */ int tcp_upstream, ssl_upstream; /** where to send it */ @@ -330,8 +312,6 @@ struct serviced_query { uint8_t* zone; /** length of zone name */ size_t zonelen; - /** qtype */ - int qtype; /** current status */ enum serviced_query_status { /** initial status */ @@ -394,9 +374,6 @@ struct serviced_query { * @param unwanted_param: user parameter to action. * @param do_udp: if udp is done. * @param sslctx: context to create outgoing connections with (if enabled). - * @param delayclose: if not 0, udp sockets are delayed before timeout closure. - * msec to wait on timeouted udp sockets. - * @param dtenv: environment to send dnstap events with (if enabled). * @return: the new structure (with no pending answers) or NULL on error. */ struct outside_network* outside_network_create(struct comm_base* base, @@ -405,7 +382,7 @@ struct outside_network* outside_network_create(struct comm_base* base, struct ub_randstate* rnd, int use_caps_for_id, int* availports, int numavailports, size_t unwanted_threshold, void (*unwanted_action)(void*), void* unwanted_param, int do_udp, - void* sslctx, int delayclose, struct dt_env *dtenv); + void* sslctx); /** * Delete outside_network structure. @@ -422,32 +399,39 @@ void outside_network_quit_prepare(struct outside_network* outnet); /** * Send UDP query, create pending answer. * Changes the ID for the query to be random and unique for that destination. - * @param sq: serviced query. + * @param outnet: provides the event handling * @param packet: wireformat query to send to destination. + * @param addr: address to send to. + * @param addrlen: length of addr. * @param timeout: in milliseconds from now. * @param callback: function to call on error, timeout or reply. * @param callback_arg: user argument for callback function. * @return: NULL on error for malloc or socket. Else the pending query object. */ -struct pending* pending_udp_query(struct serviced_query* sq, - struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback, +struct pending* pending_udp_query(struct outside_network* outnet, + ldns_buffer* packet, struct sockaddr_storage* addr, + socklen_t addrlen, int timeout, comm_point_callback_t* callback, void* callback_arg); /** * Send TCP query. May wait for TCP buffer. Selects ID to be random, and * checks id. - * @param sq: serviced query. + * @param outnet: provides the event handling. * @param packet: wireformat query to send to destination. copied from. + * @param addr: address to send to. + * @param addrlen: length of addr. * @param timeout: in seconds from now. * Timer starts running now. Timer may expire if all buffers are used, * without any query been sent to the server yet. * @param callback: function to call on error, timeout or reply. * @param callback_arg: user argument for callback function. + * @param ssl_upstream: if the tcp connection must use SSL. * @return: false on error for malloc or socket. Else the pending TCP object. */ -struct waiting_tcp* pending_tcp_query(struct serviced_query* sq, - struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback, - void* callback_arg); +struct waiting_tcp* pending_tcp_query(struct outside_network* outnet, + ldns_buffer* packet, struct sockaddr_storage* addr, + socklen_t addrlen, int timeout, comm_point_callback_t* callback, + void* callback_arg, int ssl_upstream); /** * Delete pending answer. @@ -471,7 +455,6 @@ void pending_delete(struct outside_network* outnet, struct pending* p); * If the value includes BIT_DO, DO bit is set when in EDNS queries. * @param want_dnssec: signatures are needed, without EDNS the answer is * likely to be useless. - * @param nocaps: ignore use_caps_for_id and use unperturbed qname. * @param tcp_upstream: use TCP for upstream queries. * @param ssl_upstream: use SSL for upstream queries. * @param callback: callback function. @@ -483,16 +466,18 @@ void pending_delete(struct outside_network* outnet, struct pending* p); authoritative. * @param zonelen: length of zone. * @param buff: scratch buffer to create query contents in. Empty on exit. + * @param arg_compare: function to compare callback args, return true if + * identical. It is given the callback_arg and args that are listed. * @return 0 on error, or pointer to serviced query that is used to answer * this serviced query may be shared with other callbacks as well. */ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, - uint16_t flags, int dnssec, int want_dnssec, int nocaps, - int tcp_upstream, int ssl_upstream, struct sockaddr_storage* addr, - socklen_t addrlen, uint8_t* zone, size_t zonelen, - comm_point_callback_t* callback, void* callback_arg, - struct sldns_buffer* buff); + uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream, + int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen, + uint8_t* zone, size_t zonelen, comm_point_callback_t* callback, + void* callback_arg, ldns_buffer* buff, + int (*arg_compare)(void*,void*)); /** * Remove service query callback. @@ -531,9 +516,6 @@ int outnet_tcp_cb(struct comm_point* c, void* arg, int error, /** callback for udp timeout */ void pending_udp_timer_cb(void *arg); -/** callback for udp delay for timeout */ -void pending_udp_timer_delay_cb(void *arg); - /** callback for outgoing TCP timer event */ void outnet_tcptimer(void* arg); diff --git a/usr.sbin/unbound/util/data/packed_rrset.c b/usr.sbin/unbound/util/data/packed_rrset.c index 0a5c9d3271b..e1fc2e5291e 100644 --- a/usr.sbin/unbound/util/data/packed_rrset.c +++ b/usr.sbin/unbound/util/data/packed_rrset.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,6 +40,7 @@ */ #include "config.h" +#include <ldns/wire2host.h> #include "util/data/packed_rrset.h" #include "util/data/dname.h" #include "util/storage/lookup3.h" @@ -47,9 +48,6 @@ #include "util/alloc.h" #include "util/regional.h" #include "util/net_help.h" -#include "sldns/rrdef.h" -#include "sldns/sbuffer.h" -#include "sldns/wire2str.h" void ub_packed_rrset_parsedelete(struct ub_packed_rrset_key* pkey, @@ -185,7 +183,7 @@ packed_rrset_ptr_fixup(struct packed_rrset_data* data) data->rr_len = (size_t*)((uint8_t*)data + sizeof(struct packed_rrset_data)); data->rr_data = (uint8_t**)&(data->rr_len[total]); - data->rr_ttl = (time_t*)&(data->rr_data[total]); + data->rr_ttl = (uint32_t*)&(data->rr_data[total]); nextrdata = (uint8_t*)&(data->rr_ttl[total]); for(i=0; i<total; i++) { data->rr_data[i] = nextrdata; @@ -207,7 +205,7 @@ get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname, return; if(d->rr_len[0] < 3) /* at least rdatalen + 0byte root label */ return; - len = sldns_read_uint16(d->rr_data[0]); + len = ldns_read_uint16(d->rr_data[0]); if(len != d->rr_len[0] - sizeof(uint16_t)) return; if(dname_valid(d->rr_data[0]+sizeof(uint16_t), len) != len) @@ -217,7 +215,7 @@ get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname, } void -packed_rrset_ttl_add(struct packed_rrset_data* data, time_t add) +packed_rrset_ttl_add(struct packed_rrset_data* data, uint32_t add) { size_t i; size_t total = data->count + data->rrsig_count; @@ -268,53 +266,7 @@ void log_rrset_key(enum verbosity_value v, const char* str, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); } -int packed_rr_to_string(struct ub_packed_rrset_key* rrset, size_t i, - time_t now, char* dest, size_t dest_len) -{ - struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> - entry.data; - uint8_t rr[65535]; - size_t rlen = rrset->rk.dname_len + 2 + 2 + 4 + d->rr_len[i]; - log_assert(dest_len > 0 && dest); - if(rlen > dest_len) { - dest[0] = 0; - return 0; - } - memmove(rr, rrset->rk.dname, rrset->rk.dname_len); - if(i < d->count) - memmove(rr+rrset->rk.dname_len, &rrset->rk.type, 2); - else sldns_write_uint16(rr+rrset->rk.dname_len, LDNS_RR_TYPE_RRSIG); - memmove(rr+rrset->rk.dname_len+2, &rrset->rk.rrset_class, 2); - sldns_write_uint32(rr+rrset->rk.dname_len+4, - (uint32_t)(d->rr_ttl[i]-now)); - memmove(rr+rrset->rk.dname_len+8, d->rr_data[i], d->rr_len[i]); - if(sldns_wire2str_rr_buf(rr, rlen, dest, dest_len) == -1) { - log_info("rrbuf failure %d %s", (int)d->rr_len[i], dest); - dest[0] = 0; - return 0; - } - return 1; -} - -void log_packed_rrset(enum verbosity_value v, const char* str, - struct ub_packed_rrset_key* rrset) -{ - struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> - entry.data; - char buf[65535]; - size_t i; - if(verbosity < v) - return; - for(i=0; i<d->count+d->rrsig_count; i++) { - if(!packed_rr_to_string(rrset, i, 0, buf, sizeof(buf))) { - log_info("%s: rr %d wire2str-error", str, (int)i); - } else { - log_info("%s: %s", str, buf); - } - } -} - -time_t +uint32_t ub_packed_rrset_ttl(struct ub_packed_rrset_key* key) { struct packed_rrset_data* d = (struct packed_rrset_data*)key-> @@ -324,7 +276,7 @@ ub_packed_rrset_ttl(struct ub_packed_rrset_key* key) struct ub_packed_rrset_key* packed_rrset_copy_region(struct ub_packed_rrset_key* key, - struct regional* region, time_t now) + struct regional* region, uint32_t now) { struct ub_packed_rrset_key* ck = regional_alloc(region, sizeof(struct ub_packed_rrset_key)); @@ -363,7 +315,7 @@ packed_rrset_copy_region(struct ub_packed_rrset_key* key, struct ub_packed_rrset_key* packed_rrset_copy_alloc(struct ub_packed_rrset_key* key, - struct alloc_cache* alloc, time_t now) + struct alloc_cache* alloc, uint32_t now) { struct packed_rrset_data* fd, *dd; struct ub_packed_rrset_key* dk = alloc_special_obtain(alloc); @@ -387,3 +339,150 @@ packed_rrset_copy_alloc(struct ub_packed_rrset_key* key, packed_rrset_ttl_add(dd, now); return dk; } + +struct ub_packed_rrset_key* +ub_packed_rrset_heap_key(ldns_rr_list* rrset) +{ + struct ub_packed_rrset_key* k; + ldns_rr* rr; + if(!rrset) + return NULL; + rr = ldns_rr_list_rr(rrset, 0); + if(!rr) + return NULL; + k = (struct ub_packed_rrset_key*)calloc(1, sizeof(*k)); + if(!k) + return NULL; + k->rk.type = htons(ldns_rr_get_type(rr)); + k->rk.rrset_class = htons(ldns_rr_get_class(rr)); + k->rk.dname_len = ldns_rdf_size(ldns_rr_owner(rr)); + k->rk.dname = memdup(ldns_rdf_data(ldns_rr_owner(rr)), + ldns_rdf_size(ldns_rr_owner(rr))); + if(!k->rk.dname) { + free(k); + return NULL; + } + return k; +} + +struct packed_rrset_data* +packed_rrset_heap_data(ldns_rr_list* rrset) +{ + struct packed_rrset_data* data; + size_t count=0, rrsig_count=0, len=0, i, j, total; + uint8_t* nextrdata; + if(!rrset || ldns_rr_list_rr_count(rrset)==0) + return NULL; + /* count sizes */ + for(i=0; i<ldns_rr_list_rr_count(rrset); i++) { + ldns_rr* rr = ldns_rr_list_rr(rrset, i); + if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG) + rrsig_count++; + else count++; + for(j=0; j<ldns_rr_rd_count(rr); j++) + len += ldns_rdf_size(ldns_rr_rdf(rr, j)); + len += 2; /* sizeof the rdlength */ + } + + /* allocate */ + total = count + rrsig_count; + len += sizeof(*data) + total*(sizeof(size_t) + sizeof(uint32_t) + + sizeof(uint8_t*)); + data = (struct packed_rrset_data*)calloc(1, len); + if(!data) + return NULL; + + /* fill it */ + data->ttl = ldns_rr_ttl(ldns_rr_list_rr(rrset, 0)); + data->count = count; + data->rrsig_count = rrsig_count; + data->rr_len = (size_t*)((uint8_t*)data + + sizeof(struct packed_rrset_data)); + data->rr_data = (uint8_t**)&(data->rr_len[total]); + data->rr_ttl = (uint32_t*)&(data->rr_data[total]); + nextrdata = (uint8_t*)&(data->rr_ttl[total]); + + /* fill out len, ttl, fields */ + for(i=0; i<total; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrset, i); + data->rr_ttl[i] = ldns_rr_ttl(rr); + if(data->rr_ttl[i] < data->ttl) + data->ttl = data->rr_ttl[i]; + data->rr_len[i] = 2; /* the rdlength */ + for(j=0; j<ldns_rr_rd_count(rr); j++) + data->rr_len[i] += ldns_rdf_size(ldns_rr_rdf(rr, j)); + } + + /* fixup rest of ptrs */ + for(i=0; i<total; i++) { + data->rr_data[i] = nextrdata; + nextrdata += data->rr_len[i]; + } + + /* copy data in there */ + for(i=0; i<total; i++) { + ldns_rr* rr = ldns_rr_list_rr(rrset, i); + uint16_t rdlen = htons(data->rr_len[i]-2); + size_t p = sizeof(rdlen); + memmove(data->rr_data[i], &rdlen, p); + for(j=0; j<ldns_rr_rd_count(rr); j++) { + ldns_rdf* rd = ldns_rr_rdf(rr, j); + memmove(data->rr_data[i]+p, ldns_rdf_data(rd), + ldns_rdf_size(rd)); + p += ldns_rdf_size(rd); + } + } + + if(data->rrsig_count && data->count == 0) { + data->count = data->rrsig_count; /* rrset type is RRSIG */ + data->rrsig_count = 0; + } + return data; +} + +/** convert i'th rr to ldns_rr */ +static ldns_rr* +torr(struct ub_packed_rrset_key* k, ldns_buffer* buf, size_t i) +{ + struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; + ldns_rr* rr = NULL; + size_t pos = 0; + ldns_status s; + ldns_buffer_clear(buf); + ldns_buffer_write(buf, k->rk.dname, k->rk.dname_len); + if(i < d->count) + ldns_buffer_write(buf, &k->rk.type, sizeof(uint16_t)); + else ldns_buffer_write_u16(buf, LDNS_RR_TYPE_RRSIG); + ldns_buffer_write(buf, &k->rk.rrset_class, sizeof(uint16_t)); + ldns_buffer_write_u32(buf, d->rr_ttl[i]); + ldns_buffer_write(buf, d->rr_data[i], d->rr_len[i]); + ldns_buffer_flip(buf); + s = ldns_wire2rr(&rr, ldns_buffer_begin(buf), ldns_buffer_limit(buf), + &pos, LDNS_SECTION_ANSWER); + if(s == LDNS_STATUS_OK) + return rr; + return NULL; +} + +ldns_rr_list* +packed_rrset_to_rr_list(struct ub_packed_rrset_key* k, ldns_buffer* buf) +{ + struct packed_rrset_data* d = (struct packed_rrset_data*)k->entry.data; + ldns_rr_list* r = ldns_rr_list_new(); + size_t i; + if(!r) + return NULL; + for(i=0; i<d->count+d->rrsig_count; i++) { + ldns_rr* rr = torr(k, buf, i); + if(!rr) { + ldns_rr_list_deep_free(r); + return NULL; + } + if(!ldns_rr_list_push_rr(r, rr)) { + ldns_rr_free(rr); + ldns_rr_list_deep_free(r); + return NULL; + } + } + return r; +} diff --git a/usr.sbin/unbound/util/mini_event.c b/usr.sbin/unbound/util/mini_event.c index 40dca375a01..f66214ddb8f 100644 --- a/usr.sbin/unbound/util/mini_event.c +++ b/usr.sbin/unbound/util/mini_event.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. * */ @@ -79,13 +79,13 @@ settime(struct event_base* base) return -1; } #ifndef S_SPLINT_S - *base->time_secs = (time_t)base->time_tv->tv_sec; + *base->time_secs = (uint32_t)base->time_tv->tv_sec; #endif return 0; } /** create event base */ -void *event_init(time_t* time_secs, struct timeval* time_tv) +void *event_init(uint32_t* time_secs, struct timeval* time_tv) { struct event_base* base = (struct event_base*)malloc( sizeof(struct event_base)); diff --git a/usr.sbin/unbound/util/tube.c b/usr.sbin/unbound/util/tube.c index 2106a078c8d..2fad1cafcce 100644 --- a/usr.sbin/unbound/util/tube.c +++ b/usr.sbin/unbound/util/tube.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -360,7 +360,6 @@ int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len, } d += r; } - log_assert(*len < 65536*2); *buf = (uint8_t*)malloc(*len); if(!*buf) { log_err("tube read out of memory"); @@ -368,7 +367,7 @@ int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len, return 0; } d = 0; - while(d < (ssize_t)*len) { + while(d != (ssize_t)*len) { if((r=read(fd, (*buf)+d, (size_t)((ssize_t)*len)-d)) == -1) { log_err("tube msg read failed: %s", strerror(errno)); (void)fd_set_nonblock(fd); @@ -713,7 +712,7 @@ void tube_handle_signal(int ATTR_UNUSED(fd), short ATTR_UNUSED(events), { struct tube* tube = (struct tube*)arg; uint8_t* buf; - uint32_t len = 0; + uint32_t len; verbose(VERB_ALGO, "tube handle_signal"); while(tube_poll(tube)) { if(tube_read_msg(tube, &buf, &len, 1)) { diff --git a/usr.sbin/unbound/util/winsock_event.c b/usr.sbin/unbound/util/winsock_event.c index 38661a5e1a8..ff5c9b0939d 100644 --- a/usr.sbin/unbound/util/winsock_event.c +++ b/usr.sbin/unbound/util/winsock_event.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** * \file @@ -41,10 +41,6 @@ #include "config.h" #ifdef USE_WINSOCK #include <signal.h> -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#include <sys/time.h> #include "util/winsock_event.h" #include "util/fptr_wlist.h" @@ -75,7 +71,7 @@ settime(struct event_base* base) return -1; } #ifndef S_SPLINT_S - *base->time_secs = (time_t)base->time_tv->tv_sec; + *base->time_secs = (uint32_t)base->time_tv->tv_sec; #endif return 0; } @@ -112,7 +108,7 @@ zero_waitfor(WSAEVENT waitfor[], WSAEVENT x) } } -void *event_init(time_t* time_secs, struct timeval* time_tv) +void *event_init(uint32_t* time_secs, struct timeval* time_tv) { struct event_base* base = (struct event_base*)malloc( sizeof(struct event_base)); @@ -185,8 +181,8 @@ static void handle_timeouts(struct event_base* base, struct timeval* now, wait->tv_usec = p->ev_timeout.tv_usec - now->tv_usec; } - verbose(VERB_CLIENT, "winsock_event wait=" ARG_LL "d.%6.6d", - (long long)wait->tv_sec, (int)wait->tv_usec); + verbose(VERB_CLIENT, "winsock_event wait=%d.%6.6d", + (int)wait->tv_sec, (int)wait->tv_usec); return; } #endif @@ -492,9 +488,9 @@ int event_base_set(struct event_base *base, struct event *ev) int event_add(struct event *ev, struct timeval *tv) { - verbose(VERB_ALGO, "event_add %p added=%d fd=%d tv=" ARG_LL "d %s%s%s", + verbose(VERB_ALGO, "event_add %p added=%d fd=%d tv=%d %s%s%s", ev, ev->added, ev->ev_fd, - (tv?(long long)tv->tv_sec*1000+(long long)tv->tv_usec/1000:-1), + (tv?(int)tv->tv_sec*1000+(int)tv->tv_usec/1000:-1), (ev->ev_events&EV_READ)?" EV_READ":"", (ev->ev_events&EV_WRITE)?" EV_WRITE":"", (ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":""); @@ -573,10 +569,10 @@ int event_add(struct event *ev, struct timeval *tv) int event_del(struct event *ev) { - verbose(VERB_ALGO, "event_del %p added=%d fd=%d tv=" ARG_LL "d %s%s%s", + verbose(VERB_ALGO, "event_del %p added=%d fd=%d tv=%d %s%s%s", ev, ev->added, ev->ev_fd, - (ev->ev_events&EV_TIMEOUT)?(long long)ev->ev_timeout.tv_sec*1000+ - (long long)ev->ev_timeout.tv_usec/1000:-1, + (ev->ev_events&EV_TIMEOUT)?(int)ev->ev_timeout.tv_sec*1000+ + (int)ev->ev_timeout.tv_usec/1000:-1, (ev->ev_events&EV_READ)?" EV_READ":"", (ev->ev_events&EV_WRITE)?" EV_WRITE":"", (ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":""); diff --git a/usr.sbin/unbound/validator/val_anchor.c b/usr.sbin/unbound/validator/val_anchor.c index 845b54a2e85..72338b0f8bf 100644 --- a/usr.sbin/unbound/validator/val_anchor.c +++ b/usr.sbin/unbound/validator/val_anchor.c @@ -21,16 +21,16 @@ * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ /** @@ -40,6 +40,8 @@ */ #include "config.h" #include <ctype.h> +#include <ldns/dname.h> +#include <ldns/host2wire.h> #include "validator/val_anchor.h" #include "validator/val_sigcrypt.h" #include "validator/autotrust.h" @@ -47,10 +49,8 @@ #include "util/data/dname.h" #include "util/log.h" #include "util/net_help.h" +#include "util/regional.h" #include "util/config_file.h" -#include "sldns/sbuffer.h" -#include "sldns/rrdef.h" -#include "sldns/str2wire.h" #ifdef HAVE_GLOB_H #include <glob.h> #endif @@ -77,6 +77,11 @@ anchors_create(void) struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a)); if(!a) return NULL; + a->region = regional_create(); + if(!a->region) { + free(a); + return NULL; + } a->tree = rbtree_create(anchor_cmp); if(!a->tree) { anchors_delete(a); @@ -93,45 +98,15 @@ anchors_create(void) return a; } -/** delete assembled rrset */ -static void -assembled_rrset_delete(struct ub_packed_rrset_key* pkey) -{ - if(!pkey) return; - if(pkey->entry.data) { - struct packed_rrset_data* pd = (struct packed_rrset_data*) - pkey->entry.data; - free(pd->rr_data); - free(pd->rr_ttl); - free(pd->rr_len); - free(pd); - } - free(pkey->rk.dname); - free(pkey); -} - /** destroy locks in tree and delete autotrust anchors */ static void anchors_delfunc(rbnode_t* elem, void* ATTR_UNUSED(arg)) { struct trust_anchor* ta = (struct trust_anchor*)elem; - if(!ta) return; if(ta->autr) { autr_point_delete(ta); } else { - struct ta_key* p, *np; lock_basic_destroy(&ta->lock); - free(ta->name); - p = ta->keylist; - while(p) { - np = p->next; - free(p->data); - free(p); - p = np; - } - assembled_rrset_delete(ta->ds_rrset); - assembled_rrset_delete(ta->dnskey_rrset); - free(ta); } } @@ -143,9 +118,9 @@ anchors_delete(struct val_anchors* anchors) lock_unprotect(&anchors->lock, anchors->autr); lock_unprotect(&anchors->lock, anchors); lock_basic_destroy(&anchors->lock); - if(anchors->tree) - traverse_postorder(anchors->tree, anchors_delfunc, NULL); + traverse_postorder(anchors->tree, anchors_delfunc, NULL); free(anchors->tree); + regional_destroy(anchors->region); autr_global_delete(anchors->autr); free(anchors); } @@ -218,38 +193,30 @@ anchor_find(struct val_anchors* anchors, uint8_t* name, int namelabs, /** create new trust anchor object */ static struct trust_anchor* anchor_new_ta(struct val_anchors* anchors, uint8_t* name, int namelabs, - size_t namelen, uint16_t dclass, int lockit) + size_t namelen, uint16_t dclass) { #ifdef UNBOUND_DEBUG rbnode_t* r; #endif - struct trust_anchor* ta = (struct trust_anchor*)malloc( - sizeof(struct trust_anchor)); + struct trust_anchor* ta = (struct trust_anchor*)regional_alloc( + anchors->region, sizeof(struct trust_anchor)); if(!ta) return NULL; memset(ta, 0, sizeof(*ta)); ta->node.key = ta; - ta->name = memdup(name, namelen); - if(!ta->name) { - free(ta); + ta->name = regional_alloc_init(anchors->region, name, namelen); + if(!ta->name) return NULL; - } ta->namelabs = namelabs; ta->namelen = namelen; ta->dclass = dclass; lock_basic_init(&ta->lock); - if(lockit) { - lock_basic_lock(&anchors->lock); - } + lock_basic_lock(&anchors->lock); #ifdef UNBOUND_DEBUG r = -#else - (void) #endif rbtree_insert(anchors->tree, &ta->node); - if(lockit) { - lock_basic_unlock(&anchors->lock); - } + lock_basic_unlock(&anchors->lock); log_assert(r != NULL); return ta; } @@ -270,17 +237,17 @@ anchor_find_key(struct trust_anchor* ta, uint8_t* rdata, size_t rdata_len, /** create new trustanchor key */ static struct ta_key* -anchor_new_ta_key(uint8_t* rdata, size_t rdata_len, uint16_t type) +anchor_new_ta_key(struct val_anchors* anchors, uint8_t* rdata, size_t rdata_len, + uint16_t type) { - struct ta_key* k = (struct ta_key*)malloc(sizeof(*k)); + struct ta_key* k = (struct ta_key*)regional_alloc(anchors->region, + sizeof(*k)); if(!k) return NULL; memset(k, 0, sizeof(*k)); - k->data = memdup(rdata, rdata_len); - if(!k->data) { - free(k); + k->data = regional_alloc_init(anchors->region, rdata, rdata_len); + if(!k->data) return NULL; - } k->len = rdata_len; k->type = type; return k; @@ -315,7 +282,7 @@ anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type, /* lookup or create trustanchor */ ta = anchor_find(anchors, name, namelabs, namelen, dclass); if(!ta) { - ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass, 1); + ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass); if(!ta) return NULL; lock_basic_lock(&ta->lock); @@ -329,7 +296,7 @@ anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type, lock_basic_unlock(&ta->lock); return ta; } - k = anchor_new_ta_key(rdata, rdata_len, type); + k = anchor_new_ta_key(anchors, rdata, rdata_len, type); if(!k) { lock_basic_unlock(&ta->lock); return NULL; @@ -347,26 +314,36 @@ anchor_store_new_key(struct val_anchors* anchors, uint8_t* name, uint16_t type, /** * Add new RR. It converts ldns RR to wire format. * @param anchors: anchor storage. - * @param rr: the wirerr. - * @param rl: length of rr. - * @param dl: length of dname. + * @param buffer: parsing buffer. + * @param rr: the rr (allocated by caller). * @return NULL on error, else the trust anchor. */ static struct trust_anchor* -anchor_store_new_rr(struct val_anchors* anchors, uint8_t* rr, size_t rl, - size_t dl) +anchor_store_new_rr(struct val_anchors* anchors, ldns_buffer* buffer, + ldns_rr* rr) { struct trust_anchor* ta; - if(!(ta=anchor_store_new_key(anchors, rr, - sldns_wirerr_get_type(rr, rl, dl), - sldns_wirerr_get_class(rr, rl, dl), - sldns_wirerr_get_rdatawl(rr, rl, dl), - sldns_wirerr_get_rdatalen(rr, rl, dl)+2))) { + ldns_rdf* owner = ldns_rr_owner(rr); + ldns_status status; + ldns_buffer_clear(buffer); + ldns_buffer_skip(buffer, 2); /* skip rdatalen */ + status = ldns_rr_rdata2buffer_wire(buffer, rr); + if(status != LDNS_STATUS_OK) { + log_err("error converting trustanchor to wireformat: %s", + ldns_get_errorstr_by_id(status)); + return NULL; + } + ldns_buffer_flip(buffer); + ldns_buffer_write_u16_at(buffer, 0, ldns_buffer_limit(buffer) - 2); + + if(!(ta=anchor_store_new_key(anchors, ldns_rdf_data(owner), + ldns_rr_get_type(rr), ldns_rr_get_class(rr), + ldns_buffer_begin(buffer), ldns_buffer_limit(buffer)))) { return NULL; } log_nametypeclass(VERB_QUERY, "adding trusted key", - rr, sldns_wirerr_get_type(rr, rl, dl), - sldns_wirerr_get_class(rr, rl, dl)); + ldns_rdf_data(owner), + ldns_rr_get_type(rr), ldns_rr_get_class(rr)); return ta; } @@ -380,37 +357,36 @@ static struct trust_anchor* anchor_insert_insecure(struct val_anchors* anchors, const char* str) { struct trust_anchor* ta; - size_t dname_len = 0; - uint8_t* nm = sldns_str2wire_dname(str, &dname_len); + ldns_rdf* nm = ldns_dname_new_frm_str(str); if(!nm) { log_err("parse error in domain name '%s'", str); return NULL; } - ta = anchor_store_new_key(anchors, nm, LDNS_RR_TYPE_DS, + ta = anchor_store_new_key(anchors, ldns_rdf_data(nm), LDNS_RR_TYPE_DS, LDNS_RR_CLASS_IN, NULL, 0); - free(nm); + ldns_rdf_deep_free(nm); return ta; } struct trust_anchor* -anchor_store_str(struct val_anchors* anchors, sldns_buffer* buffer, +anchor_store_str(struct val_anchors* anchors, ldns_buffer* buffer, const char* str) { struct trust_anchor* ta; - uint8_t* rr = sldns_buffer_begin(buffer); - size_t len = sldns_buffer_capacity(buffer), dname_len = 0; - int status = sldns_str2wire_rr_buf(str, rr, &len, &dname_len, - 0, NULL, 0, NULL, 0); - if(status != 0) { - log_err("error parsing trust anchor %s: at %d: %s", - str, LDNS_WIREPARSE_OFFSET(status), - sldns_get_errorstr_parse(status)); + ldns_rr* rr = NULL; + ldns_status status = ldns_rr_new_frm_str(&rr, str, 0, NULL, NULL); + if(status != LDNS_STATUS_OK) { + log_err("error parsing trust anchor: %s", + ldns_get_errorstr_by_id(status)); + ldns_rr_free(rr); return NULL; } - if(!(ta=anchor_store_new_rr(anchors, rr, len, dname_len))) { + if(!(ta=anchor_store_new_rr(anchors, buffer, rr))) { log_err("out of memory"); + ldns_rr_free(rr); return NULL; } + ldns_rr_free(rr); return ta; } @@ -423,43 +399,44 @@ anchor_store_str(struct val_anchors* anchors, sldns_buffer* buffer, * @return NULL on error. Else last trust-anchor point. */ static struct trust_anchor* -anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer, +anchor_read_file(struct val_anchors* anchors, ldns_buffer* buffer, const char* fname, int onlyone) { struct trust_anchor* ta = NULL, *tanew; - struct sldns_file_parse_state pst; - int status; - size_t len, dname_len; - uint8_t* rr = sldns_buffer_begin(buffer); + uint32_t default_ttl = 3600; + ldns_rdf* origin = NULL, *prev = NULL; + int line_nr = 1; + ldns_status status; + ldns_rr* rr; int ok = 1; FILE* in = fopen(fname, "r"); if(!in) { log_err("error opening file %s: %s", fname, strerror(errno)); return 0; } - memset(&pst, 0, sizeof(pst)); - pst.default_ttl = 3600; - pst.lineno = 1; while(!feof(in)) { - len = sldns_buffer_capacity(buffer); - dname_len = 0; - status = sldns_fp2wire_rr_buf(in, rr, &len, &dname_len, &pst); - if(len == 0) /* empty, $TTL, $ORIGIN */ + rr = NULL; + status = ldns_rr_new_frm_fp_l(&rr, in, &default_ttl, &origin, + &prev, &line_nr); + if(status == LDNS_STATUS_SYNTAX_EMPTY /* empty line */ + || status == LDNS_STATUS_SYNTAX_TTL /* $TTL */ + || status == LDNS_STATUS_SYNTAX_ORIGIN /* $ORIGIN */) continue; - if(status != 0) { - log_err("parse error in %s:%d:%d : %s", fname, - pst.lineno, LDNS_WIREPARSE_OFFSET(status), - sldns_get_errorstr_parse(status)); + if(status != LDNS_STATUS_OK) { + log_err("parse error in %s:%d : %s", fname, line_nr, + ldns_get_errorstr_by_id(status)); + ldns_rr_free(rr); ok = 0; break; } - if(sldns_wirerr_get_type(rr, len, dname_len) != - LDNS_RR_TYPE_DS && sldns_wirerr_get_type(rr, len, - dname_len) != LDNS_RR_TYPE_DNSKEY) { + if(ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS && + ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY) { + ldns_rr_free(rr); continue; } - if(!(tanew=anchor_store_new_rr(anchors, rr, len, dname_len))) { - log_err("mem error at %s line %d", fname, pst.lineno); + if(!(tanew=anchor_store_new_rr(anchors, buffer, rr))) { + log_err("error at %s line %d", fname, line_nr); + ldns_rr_free(rr); ok = 0; break; } @@ -467,12 +444,16 @@ anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer, log_err("error at %s line %d: no multiple anchor " "domains allowed (you can have multiple " "keys, but they must have the same name).", - fname, pst.lineno); + fname, line_nr); + ldns_rr_free(rr); ok = 0; break; } ta = tanew; + ldns_rr_free(rr); } + ldns_rdf_deep_free(origin); + ldns_rdf_deep_free(prev); fclose(in); if(!ok) return NULL; /* empty file is OK when multiple anchors are allowed */ @@ -527,7 +508,7 @@ is_bind_special(int c) * 0 on end of file. */ static int -readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) +readkeyword_bindfile(FILE* in, ldns_buffer* buf, int* line, int comments) { int c; int numdone = 0; @@ -537,17 +518,17 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) (*line)++; continue; } else if(comments && c=='/' && numdone>0 && /* /_/ bla*/ - sldns_buffer_read_u8_at(buf, - sldns_buffer_position(buf)-1) == '/') { - sldns_buffer_skip(buf, -1); + ldns_buffer_read_u8_at(buf, + ldns_buffer_position(buf)-1) == '/') { + ldns_buffer_skip(buf, -1); numdone--; skip_to_eol(in); (*line)++; continue; } else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */ - sldns_buffer_read_u8_at(buf, - sldns_buffer_position(buf)-1) == '/') { - sldns_buffer_skip(buf, -1); + ldns_buffer_read_u8_at(buf, + ldns_buffer_position(buf)-1) == '/') { + ldns_buffer_skip(buf, -1); numdone--; /* skip to end of comment */ while(c != EOF && (c=getc(in)) != EOF ) { @@ -563,7 +544,7 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) /* not a comment, complete the keyword */ if(numdone > 0) { /* check same type */ - if(isspace((unsigned char)c)) { + if(isspace(c)) { ungetc(c, in); return numdone; } @@ -577,17 +558,17 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) (*line)++; } /* space for 1 char + 0 string terminator */ - if(sldns_buffer_remaining(buf) < 2) { + if(ldns_buffer_remaining(buf) < 2) { fatal_exit("trusted-keys, %d, string too long", *line); } - sldns_buffer_write_u8(buf, (uint8_t)c); + ldns_buffer_write_u8(buf, (uint8_t)c); numdone++; - if(isspace((unsigned char)c)) { + if(isspace(c)) { /* collate whitespace into ' ' */ while((c = getc(in)) != EOF ) { if(c == '\n') (*line)++; - if(!isspace((unsigned char)c)) { + if(!isspace(c)) { ungetc(c, in); break; } @@ -602,17 +583,17 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) /** skip through file to { or ; */ static int -skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec) +skip_to_special(FILE* in, ldns_buffer* buf, int* line, int spec) { int rdlen; - sldns_buffer_clear(buf); + ldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, 1))) { - if(rdlen == 1 && isspace((unsigned char)*sldns_buffer_begin(buf))) { - sldns_buffer_clear(buf); + if(rdlen == 1 && isspace((int)*ldns_buffer_begin(buf))) { + ldns_buffer_clear(buf); continue; } - if(rdlen != 1 || *sldns_buffer_begin(buf) != (uint8_t)spec) { - sldns_buffer_write_u8(buf, 0); + if(rdlen != 1 || *ldns_buffer_begin(buf) != (uint8_t)spec) { + ldns_buffer_write_u8(buf, 0); log_err("trusted-keys, line %d, expected %c", *line, spec); return 0; @@ -632,7 +613,7 @@ skip_to_special(FILE* in, sldns_buffer* buf, int* line, int spec) * @return 0 on error. */ static int -process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, +process_bind_contents(struct val_anchors* anchors, ldns_buffer* buf, int* line, FILE* in) { /* loop over contents, collate strings before ; */ @@ -645,41 +626,41 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, int comments = 1; int rdlen; char* str = 0; - sldns_buffer_clear(buf); + ldns_buffer_clear(buf); while((rdlen=readkeyword_bindfile(in, buf, line, comments))) { - if(rdlen == 1 && sldns_buffer_position(buf) == 1 - && isspace((unsigned char)*sldns_buffer_begin(buf))) { + if(rdlen == 1 && ldns_buffer_position(buf) == 1 + && isspace((int)*ldns_buffer_begin(buf))) { /* starting whitespace is removed */ - sldns_buffer_clear(buf); + ldns_buffer_clear(buf); continue; - } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '"') { + } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '"') { /* remove " from the string */ if(contnum == 0) { quoted = 1; comments = 0; } - sldns_buffer_skip(buf, -1); + ldns_buffer_skip(buf, -1); if(contnum > 0 && quoted) { - if(sldns_buffer_remaining(buf) < 8+1) { + if(ldns_buffer_remaining(buf) < 8+1) { log_err("line %d, too long", *line); return 0; } - sldns_buffer_write(buf, " DNSKEY ", 8); + ldns_buffer_write(buf, " DNSKEY ", 8); quoted = 0; comments = 1; } else if(contnum > 0) comments = !comments; continue; - } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == ';') { + } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == ';') { if(contnum < 5) { - sldns_buffer_write_u8(buf, 0); + ldns_buffer_write_u8(buf, 0); log_err("line %d, bad key", *line); return 0; } - sldns_buffer_skip(buf, -1); - sldns_buffer_write_u8(buf, 0); - str = strdup((char*)sldns_buffer_begin(buf)); + ldns_buffer_skip(buf, -1); + ldns_buffer_write_u8(buf, 0); + str = strdup((char*)ldns_buffer_begin(buf)); if(!str) { log_err("line %d, allocation failure", *line); return 0; @@ -690,30 +671,30 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, return 0; } free(str); - sldns_buffer_clear(buf); + ldns_buffer_clear(buf); contnum = 0; quoted = 0; comments = 1; continue; - } else if(rdlen == 1 && sldns_buffer_current(buf)[-1] == '}') { + } else if(rdlen == 1 && ldns_buffer_current(buf)[-1] == '}') { if(contnum > 0) { - sldns_buffer_write_u8(buf, 0); + ldns_buffer_write_u8(buf, 0); log_err("line %d, bad key before }", *line); return 0; } return 1; } else if(rdlen == 1 && - isspace((unsigned char)sldns_buffer_current(buf)[-1])) { + isspace((int)ldns_buffer_current(buf)[-1])) { /* leave whitespace here */ } else { /* not space or whatnot, so actual content */ contnum ++; if(contnum == 1 && !quoted) { - if(sldns_buffer_remaining(buf) < 8+1) { + if(ldns_buffer_remaining(buf) < 8+1) { log_err("line %d, too long", *line); return 0; } - sldns_buffer_write(buf, " DNSKEY ", 8); + ldns_buffer_write(buf, " DNSKEY ", 8); } } } @@ -730,7 +711,7 @@ process_bind_contents(struct val_anchors* anchors, sldns_buffer* buf, * @return false on error. */ static int -anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer, +anchor_read_bind_file(struct val_anchors* anchors, ldns_buffer* buffer, const char* fname) { int line_nr = 1; @@ -742,11 +723,11 @@ anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer, } verbose(VERB_QUERY, "reading in bind-compat-mode: '%s'", fname); /* scan for trusted-keys keyword, ignore everything else */ - sldns_buffer_clear(buffer); + ldns_buffer_clear(buffer); while((rdlen=readkeyword_bindfile(in, buffer, &line_nr, 1)) != 0) { - if(rdlen != 12 || strncmp((char*)sldns_buffer_begin(buffer), + if(rdlen != 12 || strncmp((char*)ldns_buffer_begin(buffer), "trusted-keys", 12) != 0) { - sldns_buffer_clear(buffer); + ldns_buffer_clear(buffer); /* ignore everything but trusted-keys */ continue; } @@ -766,7 +747,7 @@ anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer, fclose(in); return 0; } - sldns_buffer_clear(buffer); + ldns_buffer_clear(buffer); } fclose(in); return 1; @@ -781,7 +762,7 @@ anchor_read_bind_file(struct val_anchors* anchors, sldns_buffer* buffer, * @return false on error. */ static int -anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer, +anchor_read_bind_file_wild(struct val_anchors* anchors, ldns_buffer* buffer, const char* pat) { #ifdef HAVE_GLOB @@ -825,8 +806,7 @@ anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer, log_err("wildcard trusted-keys-file %s: expansion " "failed (%s)", pat, strerror(errno)); } - /* ignore globs that yield no files */ - return 1; + return 0; } /* process files found, if any */ for(i=0; i<(size_t)g.gl_pathc; i++) { @@ -846,73 +826,55 @@ anchor_read_bind_file_wild(struct val_anchors* anchors, sldns_buffer* buffer, /** * Assemble an rrset structure for the type + * @param region: allocated in this region. * @param ta: trust anchor. * @param num: number of items to fetch from list. * @param type: fetch only items of this type. * @return rrset or NULL on error. */ static struct ub_packed_rrset_key* -assemble_it(struct trust_anchor* ta, size_t num, uint16_t type) +assemble_it(struct regional* region, struct trust_anchor* ta, size_t num, + uint16_t type) { struct ub_packed_rrset_key* pkey = (struct ub_packed_rrset_key*) - malloc(sizeof(*pkey)); + regional_alloc(region, sizeof(*pkey)); struct packed_rrset_data* pd; struct ta_key* tk; size_t i; if(!pkey) return NULL; memset(pkey, 0, sizeof(*pkey)); - pkey->rk.dname = memdup(ta->name, ta->namelen); - if(!pkey->rk.dname) { - free(pkey); + pkey->rk.dname = regional_alloc_init(region, ta->name, ta->namelen); + if(!pkey->rk.dname) return NULL; - } - + pkey->rk.dname_len = ta->namelen; pkey->rk.type = htons(type); pkey->rk.rrset_class = htons(ta->dclass); /* The rrset is build in an uncompressed way. This means it * cannot be copied in the normal way. */ - pd = (struct packed_rrset_data*)malloc(sizeof(*pd)); - if(!pd) { - free(pkey->rk.dname); - free(pkey); + pd = (struct packed_rrset_data*)regional_alloc(region, sizeof(*pd)); + if(!pd) return NULL; - } memset(pd, 0, sizeof(*pd)); pd->count = num; pd->trust = rrset_trust_ultimate; - pd->rr_len = (size_t*)reallocarray(NULL, num, sizeof(size_t)); - if(!pd->rr_len) { - free(pd); - free(pkey->rk.dname); - free(pkey); + pd->rr_len = (size_t*)regional_alloc(region, num*sizeof(size_t)); + if(!pd->rr_len) return NULL; - } - pd->rr_ttl = (time_t*)reallocarray(NULL, num, sizeof(time_t)); - if(!pd->rr_ttl) { - free(pd->rr_len); - free(pd); - free(pkey->rk.dname); - free(pkey); + pd->rr_ttl = (uint32_t*)regional_alloc(region, num*sizeof(uint32_t)); + if(!pd->rr_ttl) return NULL; - } - pd->rr_data = (uint8_t**)reallocarray(NULL, num, sizeof(uint8_t*)); - if(!pd->rr_data) { - free(pd->rr_ttl); - free(pd->rr_len); - free(pd); - free(pkey->rk.dname); - free(pkey); + pd->rr_data = (uint8_t**)regional_alloc(region, num*sizeof(uint8_t*)); + if(!pd->rr_data) return NULL; - } /* fill in rrs */ i=0; for(tk = ta->keylist; tk; tk = tk->next) { if(tk->type != type) continue; pd->rr_len[i] = tk->len; - /* reuse data ptr to allocation in talist */ + /* reuse data ptr to allocation in region */ pd->rr_data[i] = tk->data; pd->rr_ttl[i] = 0; i++; @@ -923,20 +885,22 @@ assemble_it(struct trust_anchor* ta, size_t num, uint16_t type) /** * Assemble structures for the trust DS and DNSKEY rrsets. + * @param anchors: trust anchor storage. * @param ta: trust anchor * @return: false on error. */ static int -anchors_assemble(struct trust_anchor* ta) +anchors_assemble(struct val_anchors* anchors, struct trust_anchor* ta) { if(ta->numDS > 0) { - ta->ds_rrset = assemble_it(ta, ta->numDS, LDNS_RR_TYPE_DS); + ta->ds_rrset = assemble_it(anchors->region, ta, + ta->numDS, LDNS_RR_TYPE_DS); if(!ta->ds_rrset) return 0; } if(ta->numDNSKEY > 0) { - ta->dnskey_rrset = assemble_it(ta, ta->numDNSKEY, - LDNS_RR_TYPE_DNSKEY); + ta->dnskey_rrset = assemble_it(anchors->region, ta, + ta->numDNSKEY, LDNS_RR_TYPE_DNSKEY); if(!ta->dnskey_rrset) return 0; } @@ -997,7 +961,7 @@ anchors_assemble_rrsets(struct val_anchors* anchors) ta = next; /* skip */ continue; } - if(!anchors_assemble(ta)) { + if(!anchors_assemble(anchors, ta)) { log_err("out of memory"); lock_basic_unlock(&ta->lock); lock_basic_unlock(&anchors->lock); @@ -1020,16 +984,10 @@ anchors_assemble_rrsets(struct val_anchors* anchors) dname_str(ta->name, b); log_warn("trust anchor %s has no supported algorithms," " the anchor is ignored (check if you need to" - " upgrade unbound and " -#ifdef HAVE_LIBRESSL - "libressl" -#else - "openssl" -#endif - ")", b); + " upgrade unbound and openssl)", b); (void)rbtree_delete(anchors->tree, &ta->node); lock_basic_unlock(&ta->lock); - anchors_delfunc(&ta->node, NULL); + lock_basic_destroy(&ta->lock); ta = next; continue; } @@ -1045,13 +1003,13 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) { struct config_strlist* f; char* nm; - sldns_buffer* parsebuf = sldns_buffer_new(65535); + ldns_buffer* parsebuf = ldns_buffer_new(65535); for(f = cfg->domain_insecure; f; f = f->next) { if(!f->str || f->str[0] == 0) /* empty "" */ continue; if(!anchor_insert_insecure(anchors, f->str)) { log_err("error in domain-insecure: %s", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } } @@ -1064,7 +1022,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) nm += strlen(cfg->chrootdir); if(!anchor_read_file(anchors, parsebuf, nm, 0)) { log_err("error reading trust-anchor-file: %s", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } } @@ -1077,7 +1035,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) nm += strlen(cfg->chrootdir); if(!anchor_read_bind_file_wild(anchors, parsebuf, nm)) { log_err("error reading trusted-keys-file: %s", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } } @@ -1086,7 +1044,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) continue; if(!anchor_store_str(anchors, parsebuf, f->str)) { log_err("error in trust-anchor: \"%s\"", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } } @@ -1100,7 +1058,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) nm, 1))) { log_err("error reading dlv-anchor-file: %s", cfg->dlv_anchor_file); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } lock_basic_lock(&anchors->lock); @@ -1114,7 +1072,7 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) if(!(dlva = anchor_store_str( anchors, parsebuf, f->str))) { log_err("error in dlv-anchor: \"%s\"", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } lock_basic_lock(&anchors->lock); @@ -1133,14 +1091,14 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg) if(!autr_read_file(anchors, nm)) { log_err("error reading auto-trust-anchor-file: %s", f->str); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); return 0; } } /* first assemble, since it may delete useless anchors */ anchors_assemble_rrsets(anchors); init_parents(anchors); - sldns_buffer_free(parsebuf); + ldns_buffer_free(parsebuf); if(verbosity >= VERB_ALGO) autr_debug_print(anchors); return 1; } @@ -1188,75 +1146,5 @@ anchors_lookup(struct val_anchors* anchors, size_t anchors_get_mem(struct val_anchors* anchors) { - struct trust_anchor *ta; - size_t s = sizeof(*anchors); - if(!anchors) - return 0; - RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) { - s += sizeof(*ta) + ta->namelen; - /* keys and so on */ - } - return s; + return sizeof(*anchors) + regional_get_mem(anchors->region); } - -int -anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm) -{ - struct trust_anchor key; - key.node.key = &key; - key.name = nm; - key.namelabs = dname_count_size_labels(nm, &key.namelen); - key.dclass = c; - lock_basic_lock(&anchors->lock); - if(rbtree_search(anchors->tree, &key)) { - lock_basic_unlock(&anchors->lock); - /* nothing to do, already an anchor or insecure point */ - return 1; - } - if(!anchor_new_ta(anchors, nm, key.namelabs, key.namelen, c, 0)) { - log_err("out of memory"); - lock_basic_unlock(&anchors->lock); - return 0; - } - /* no other contents in new ta, because it is insecure point */ - anchors_init_parents_locked(anchors); - lock_basic_unlock(&anchors->lock); - return 1; -} - -void -anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, - uint8_t* nm) -{ - struct trust_anchor key; - struct trust_anchor* ta; - key.node.key = &key; - key.name = nm; - key.namelabs = dname_count_size_labels(nm, &key.namelen); - key.dclass = c; - lock_basic_lock(&anchors->lock); - if(!(ta=(struct trust_anchor*)rbtree_search(anchors->tree, &key))) { - lock_basic_unlock(&anchors->lock); - /* nothing there */ - return; - } - /* lock it to drive away other threads that use it */ - lock_basic_lock(&ta->lock); - /* see if its really an insecure point */ - if(ta->keylist || ta->autr || ta->numDS || ta->numDNSKEY) { - lock_basic_unlock(&anchors->lock); - lock_basic_unlock(&ta->lock); - /* its not an insecure point, do not remove it */ - return; - } - - /* remove from tree */ - (void)rbtree_delete(anchors->tree, &ta->node); - anchors_init_parents_locked(anchors); - lock_basic_unlock(&anchors->lock); - - /* actual free of data */ - lock_basic_unlock(&ta->lock); - anchors_delfunc(&ta->node, NULL); -} - |