diff --git a/.travis.yml b/.travis.yml index 37ea672b3..1f514b5d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,8 @@ addons: - openssl - libevent - expat - update: true + # homebrew update takes 20min or hangs, so disable update + #update: true jobs: include: @@ -26,18 +27,22 @@ jobs: env: - CONFIG_OPTS="--enable-debug --disable-flto" - os: linux - name: Clang on Linux, Amd64 + name: Clang on Linux, Amd64, clang-analysis compiler: clang arch: amd64 env: - CONFIG_OPTS="--enable-debug --disable-flto" + - TEST_ANALYZER=yes - os: osx - name: Clang on OS X, Amd64 + osx_image: xcode12.2 + name: Clang on OS X, Amd64, clang-analysis compiler: clang arch: amd64 env: - TEST_OSX=yes - - CONFIG_OPTS="--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/" + - CONFIG_OPTS="--enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl --with-libexpat=/usr/local/opt/expat" + - TEST_ANALYZER=yes + - HOMEBREW_NO_AUTO_UPDATE=1 - os: linux name: Libevent, GCC on Linux, Amd64 compiler: gcc @@ -53,13 +58,15 @@ jobs: - TEST_LIBEVENT=yes - CONFIG_OPTS="--with-libevent" - os: osx + osx_image: xcode12.2 name: Libevent, Clang on OS X, Amd64 compiler: clang arch: amd64 env: - TEST_OSX=yes - TEST_LIBEVENT=yes - - CONFIG_OPTS="--with-ssl=/usr/local/opt/openssl/ --with-libevent=/usr/local/opt/libevent/" + - CONFIG_OPTS="--disable-flto --with-ssl=/usr/local/opt/openssl --with-libevent=/usr/local/opt/libevent --with-libexpat=/usr/local/opt/expat" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: linux name: UBsan, GCC on Linux, Amd64 compiler: gcc @@ -131,7 +138,7 @@ jobs: env: - CONFIG_OPTS="--enable-debug --disable-flto" - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: Apple iPhone on iOS, armv7 compiler: clang env: @@ -141,8 +148,9 @@ jobs: - IOS_SDK=iPhoneOS - IOS_CPU=armv7s - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: Apple iPhone on iOS, arm64 compiler: clang env: @@ -152,8 +160,9 @@ jobs: - IOS_SDK=iPhoneOS - IOS_CPU=arm64 - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: Apple TV on iOS, arm64 compiler: clang env: @@ -163,8 +172,9 @@ jobs: - IOS_SDK=AppleTVOS - IOS_CPU=arm64 - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: Apple Watch on iOS, armv7 compiler: clang env: @@ -174,8 +184,9 @@ jobs: - IOS_SDK=WatchOS - IOS_CPU=armv7k - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: iPhoneSimulator on OS X, i386 env: - TEST_IOS=yes @@ -184,8 +195,9 @@ jobs: - IOS_CPU=i386 - IOS_SDK=iPhoneSimulator - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: iPhoneSimulator on OS X, x86_64 env: - TEST_IOS=yes @@ -194,8 +206,9 @@ jobs: - IOS_CPU=x86_64 - IOS_SDK=iPhoneSimulator - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: AppleTVSimulator on OS X, x86_64 env: - TEST_IOS=yes @@ -204,8 +217,9 @@ jobs: - IOS_CPU=x86_64 - IOS_SDK=AppleTVSimulator - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: osx - osx_image: xcode10 + osx_image: xcode12.2 name: WatchSimulator on OS X, i386 env: - TEST_IOS=yes @@ -214,6 +228,7 @@ jobs: - IOS_CPU=i386 - IOS_SDK=WatchSimulator - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU" + - HOMEBREW_NO_AUTO_UPDATE=1 - os: linux name: Android armv7a, Linux, Amd64 compiler: clang @@ -272,6 +287,22 @@ jobs: - ANDROID_NDK_ROOT="$HOME/android-ndk" allow_failures: + - os: osx + name: Apple iPhone on iOS, armv7 + - os: osx + name: Apple iPhone on iOS, arm64 + - os: osx + name: Apple TV on iOS, arm64 + - os: osx + name: Apple Watch on iOS, armv7 + - os: osx + name: iPhoneSimulator on OS X, i386 + - os: osx + name: iPhoneSimulator on OS X, x86_64 + - os: osx + name: AppleTVSimulator on OS X, x86_64 + - os: osx + name: WatchSimulator on OS X, i386 - os: linux name: Android armv7a, Linux, Amd64 - os: linux @@ -294,51 +325,56 @@ before_script: # https://docs.travis-ci.com/user/job-lifecycle/ in the Travis docs. script: - | + export MAKE_TEST="yes" if [ "$TEST_UBSAN" = "yes" ]; then - export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover" - ./configure - make -j 2 - make test + export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover=all" elif [ "$TEST_ASAN" = "yes" ]; then export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address" - ./configure - make -j 2 - make test - elif [ "$TEST_IOS" = "yes" ]; then + fi + - | + if [ "$TEST_IOS" = "yes" ]; then export AUTOTOOLS_BUILD="$(./config.guess)" export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig" source ./contrib/ios/setenv_ios.sh ./contrib/ios/install_openssl.sh ./contrib/ios/install_expat.sh - ./configure \ - --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \ - --prefix="$IOS_PREFIX" \ - --with-ssl="$IOS_PREFIX" --disable-gost \ - --with-libexpat="$IOS_PREFIX"; - make -j 2 - make install - elif [ "$TEST_ANDROID" = "yes" ]; then + export CONFIG_OPTS="\ + --build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST \ + --prefix=$IOS_PREFIX \ + --with-ssl=$IOS_PREFIX --disable-gost \ + --with-libexpat=$IOS_PREFIX " + echo CONFIG_OPTS ${CONFIG_OPTS} + export MAKE_TEST=no + export TEST_INSTALL=yes + fi + - | + if [ "$TEST_ANDROID" = "yes" ]; then export AUTOTOOLS_BUILD="$(./config.guess)" export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig" ./contrib/android/install_ndk.sh source ./contrib/android/setenv_android.sh ./contrib/android/install_openssl.sh ./contrib/android/install_expat.sh - ./configure \ - --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \ - --prefix="$ANDROID_PREFIX" \ - --with-ssl="$ANDROID_PREFIX" --disable-gost \ - --with-libexpat="$ANDROID_PREFIX"; - make -j 2 + export CONFIG_OPTS="\ + --build=$AUTOTOOLS_BUILD --host=$AUTOTOOLS_HOST \ + --prefix=$ANDROID_PREFIX \ + --with-ssl=$ANDROID_PREFIX --disable-gost \ + --with-libexpat=$ANDROID_PREFIX " + echo CONFIG_OPTS ${CONFIG_OPTS} + export MAKE_TEST=no + export TEST_INSTALL=yes + fi + - ./configure ${CONFIG_OPTS} + - make -j 2 + - | + if [ "$MAKE_TEST" = "yes" ]; then + make test + fi + - | + if [ "$TEST_INSTALL" = "yes" ]; then make install - elif [ "$TEST_OSX" = "yes" ]; then - ./configure --enable-debug --disable-flto --with-ssl=/usr/local/opt/openssl/ - make -j 2 - make test - (cd testdata/clang-analysis.tdir; bash clang-analysis.test) - else - ./configure ${CONFIG_OPTS} - make -j 2 - make test + fi + - | + if [ "$TEST_ANALYZER" = "yes" ]; then (cd testdata/clang-analysis.tdir; bash clang-analysis.test) fi diff --git a/Makefile.in b/Makefile.in index b640af006..69ce8e9b2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -110,6 +110,8 @@ SUBNET_HEADER=@SUBNET_HEADER@ IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c IPSECMOD_OBJ=@IPSECMOD_OBJ@ IPSECMOD_HEADER=@IPSECMOD_HEADER@ +CACHEDB_SRC=@CACHEDB_SRC@ +CACHEDB_OBJ=@CACHEDB_OBJ@ COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \ util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \ @@ -133,7 +135,7 @@ validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \ edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \ edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \ -cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \ +$(CACHEDB_SRC) respip/respip.c $(CHECKLOCK_SRC) \ $(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC) COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \ @@ -145,7 +147,7 @@ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \ slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \ autotrust.lo val_anchor.lo rpz.lo \ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \ -val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \ +val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \ $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \ $(IPSECMOD_OBJ) $(IPSET_OBJ) $(DYNLIBMOD_OBJ) respip.lo COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \ @@ -431,6 +433,8 @@ dtstream.lo dtstream.o: $(srcdir)/dnstap/dtstream.c config.h $(srcdir)/dnstap/dt dnstap_fstrm.lo dnstap_fstrm.o: $(srcdir)/dnstap/dnstap_fstrm.c config.h $(srcdir)/dnstap/dnstap_fstrm.h unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h $(srcdir)/dnstap/dtstream.h dynlibmod.lo dynlibdmod.o: $(srcdir)/dynlibmod/dynlibmod.c config.h $(srcdir)/dynlibmod/dynlibmod.h +cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h +redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h $(srcdir)/cachedb/redis.h # dnscrypt dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \ @@ -464,7 +468,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i un # Pyunbound python unbound wrapper _unbound.la: libunbound_wrap.lo libunbound.la - $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs -lunbound + $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs -lunbound $(LIBS) util/config_file.c: util/configparser.h util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h diff --git a/README.md b/README.md index 3e11ce58c..c8877d1e9 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound) [![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound) +[![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest) Unbound is a validating, recursive, caching DNS resolver. It is designed to be fast and lean and incorporates modern features based on open standards. If you diff --git a/acx_nlnetlabs.m4 b/acx_nlnetlabs.m4 index d33352f17..dd8d8c329 100644 --- a/acx_nlnetlabs.m4 +++ b/acx_nlnetlabs.m4 @@ -2,7 +2,8 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 37 +# Version 38 +# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS. # 2021-01-05 fix defun for aclocal # 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE # 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0). @@ -888,7 +889,7 @@ AC_CACHE_VAL(cv_cc_deprecated_$cache, [ echo '$3' >conftest.c echo 'void f(){ $2 }' >>conftest.c -if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then +if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then eval "cv_cc_deprecated_$cache=no" else eval "cv_cc_deprecated_$cache=yes" diff --git a/configure b/configure index b067e48fe..6099122b1 100755 --- a/configure +++ b/configure @@ -643,6 +643,8 @@ IPSET_OBJ IPSET_SRC IPSECMOD_HEADER IPSECMOD_OBJ +CACHEDB_OBJ +CACHEDB_SRC DNSCRYPT_OBJ DNSCRYPT_SRC ENABLE_DNSCRYPT @@ -14793,7 +14795,8 @@ done # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH for ac_header in TargetConditionals.h do : - ac_fn_c_check_header_mongrel "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default" + ac_fn_c_check_header_compile "$LINENO" "TargetConditionals.h" "ac_cv_header_TargetConditionals_h" "$ac_includes_default +" if test "x$ac_cv_header_TargetConditionals_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TARGETCONDITIONALS_H 1 @@ -20149,9 +20152,10 @@ else echo ' #include +#include ' >conftest.c echo 'void f(){ (void)daemon(0, 0); }' >>conftest.c -if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then +if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then eval "cv_cc_deprecated_$cache=no" else eval "cv_cc_deprecated_$cache=yes" @@ -21511,6 +21515,10 @@ case "$enable_cachedb" in $as_echo "#define USE_CACHEDB 1" >>confdefs.h + CACHEDB_SRC="cachedb/cachedb.c cachedb/redis.c" + + CACHEDB_OBJ="cachedb.lo redis.lo" + ;; no|*) # nothing diff --git a/configure.ac b/configure.ac index cba6ca018..efbdfe6aa 100644 --- a/configure.ac +++ b/configure.ac @@ -407,7 +407,7 @@ AC_CHECK_HEADERS([net/if.h],,, [ ]) # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH -AC_CHECK_HEADERS([TargetConditionals.h]) +AC_CHECK_HEADERS([TargetConditionals.h],,, [AC_INCLUDES_DEFAULT]) # check for types. # Using own tests for int64* because autoconf builtin only give 32bit. @@ -1509,6 +1509,7 @@ AC_CHECK_FUNCS([daemon]) if test $ac_cv_func_daemon = yes; then ACX_FUNC_DEPRECATED([daemon], [(void)daemon(0, 0);], [ #include +#include ]) fi @@ -1779,6 +1780,8 @@ if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi case "$enable_cachedb" in yes) AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support]) + AC_SUBST([CACHEDB_SRC], ["cachedb/cachedb.c cachedb/redis.c"]) + AC_SUBST([CACHEDB_OBJ], ["cachedb.lo redis.lo"]) ;; no|*) # nothing diff --git a/contrib/ios/install_tools.sh b/contrib/ios/install_tools.sh index 55fef454e..e2f381425 100755 --- a/contrib/ios/install_tools.sh +++ b/contrib/ios/install_tools.sh @@ -1,8 +1,10 @@ #!/usr/bin/env bash # This step should install tools needed for all packages - OpenSSL, Expat and Unbound -echo "Updating tools" -brew update 1>/dev/null +# brew update hangs, so we try to skip that step. +#echo "Updating tools" +#brew update 1>/dev/null echo "Installing tools" # already installed are: autoconf automake libtool pkg-config -brew install curl perl 1>/dev/null +#brew install curl perl 1>/dev/null +HOMEBREW_NO_AUTO_UPDATE=1 brew install curl perl 1>/dev/null diff --git a/dnscrypt/dnscrypt.c b/dnscrypt/dnscrypt.c index 843735018..9b324ae69 100644 --- a/dnscrypt/dnscrypt.c +++ b/dnscrypt/dnscrypt.c @@ -863,6 +863,7 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg) return cert_id; } +#ifdef SODIUM_MISUSE_HANDLER static void sodium_misuse_handler(void) { @@ -872,6 +873,7 @@ sodium_misuse_handler(void) " unbound in a chroot, make sure /dev/urandom is available. See" " https://www.unbound.net/documentation/unbound.conf.html"); } +#endif /** diff --git a/doc/Changelog b/doc/Changelog index b6bbfa210..d5412a2a0 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,42 @@ +25 March 2021: Wouter + - Fix #429: Also fix end of transfer for http download of auth zones. + +24 March 2021: Wouter + - Fix deprecation test to work for iOS TVOS and WatchOS, it uses + CFLAGS and CPPFLAGS and also checks if the item is unavailable. + - Travis, fix script to fail when tasks fail. + - Travis, fix warning in ubsan compile. + - Fix configure Targetconfiditionals.h header check, to use compile. + - Fix that cachedb does not produce empty object files when disabled. + +23 March 2021: Wouter + - Travis enable all tests again. Clang analyzer only a couple times, + when there is a difference. homebrew updates disabled, so it does + not hang. removed trailing slashes from configure paths. Moved iOS + tests to allow-failure. + - travis, analyzer disabled on test without debug, that does not + run anway. Turn off failing tests except one. Update iOS test + to xcode image 12.2. + +22 March 2021: George + - Fix unused-function warning when compiling with --enable-dnscrypt. + - Fix for #367: fix memory leak when cannot bind to listening port. + - Reformat pythonmod/pythonmod_utils.{c,h}. + +22 March 2021: Wouter + - Merge #449 from orbea: build: Add missing linker flags. + - iana portlist update. + - Comment out nonworking OSX and IOS travis tests, vm fails to start. + - Fix compile error in listen_dnsport on Android. + - Fix memory leak reported by asan in rpz SOA record query name. + +19 March 2021: Wouter + - Fix for #447: squelch connection refused tcp connection failures + from the log, unless verbosity is high. + +17 March 2021: Wouter + - Fix #441: Minimal NSEC range not accepted for top level domains. + 11 March 2021: Wouter - Fix parse of LOC RR type for decimetres. diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c index aae934dd4..f093c1bf9 100644 --- a/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c @@ -640,25 +640,37 @@ store_rrset(sldns_buffer* pkt, struct msg_parse* msg, struct module_env* env, /** * Check if right hand name in NSEC is within zone + * @param pkt: the packet buffer for decompression. * @param rrset: the NSEC rrset * @param zonename: the zone name. * @return true if BAD. */ -static int sanitize_nsec_is_overreach(struct rrset_parse* rrset, - uint8_t* zonename) +static int sanitize_nsec_is_overreach(sldns_buffer* pkt, + struct rrset_parse* rrset, uint8_t* zonename) { struct rr_parse* rr; uint8_t* rhs; size_t len; log_assert(rrset->type == LDNS_RR_TYPE_NSEC); for(rr = rrset->rr_first; rr; rr = rr->next) { + size_t pos = sldns_buffer_position(pkt); + size_t rhspos; rhs = rr->ttl_data+4+2; len = sldns_read_uint16(rr->ttl_data+4); - if(!dname_valid(rhs, len)) { - /* malformed domain name in rdata */ + rhspos = rhs-sldns_buffer_begin(pkt); + sldns_buffer_set_position(pkt, rhspos); + if(pkt_dname_len(pkt) == 0) { + /* malformed */ + sldns_buffer_set_position(pkt, pos); return 1; } - if(!dname_subdomain_c(rhs, zonename)) { + if(sldns_buffer_position(pkt)-rhspos > len) { + /* outside of rdata boundaries */ + sldns_buffer_set_position(pkt, pos); + return 1; + } + sldns_buffer_set_position(pkt, pos); + if(!pkt_sub(pkt, rhs, zonename)) { /* overreaching */ return 1; } @@ -791,7 +803,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, } /* check if right hand side of NSEC is within zone */ if(rrset->type == LDNS_RR_TYPE_NSEC && - sanitize_nsec_is_overreach(rrset, zonename)) { + sanitize_nsec_is_overreach(pkt, rrset, zonename)) { remove_rrset("sanitize: removing overreaching NSEC " "RRset:", pkt, msg, prev, &rrset); continue; diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c index 9f7282540..21a16bbe8 100644 --- a/pythonmod/pythonmod_utils.c +++ b/pythonmod/pythonmod_utils.c @@ -5,18 +5,18 @@ * Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz) * * This software is open source. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * * Neither the name of the organization nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. @@ -56,113 +56,118 @@ #undef _XOPEN_SOURCE #include -/* Store the reply_info and query_info pair in message cache (qstate->msg_cache) */ -int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral) +/* Store the reply_info and query_info pair in message cache + * (qstate->msg_cache) */ +int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, + struct reply_info* msgrep, int is_referral) { - if (!msgrep) - return 0; + if (!msgrep) + return 0; - if (msgrep->authoritative) /*authoritative answer can't be stored in cache*/ - { - PyErr_SetString(PyExc_ValueError, "Authoritative answer can't be stored"); - return 0; - } + /* authoritative answer can't be stored in cache */ + if (msgrep->authoritative) { + PyErr_SetString(PyExc_ValueError, + "Authoritative answer can't be stored"); + return 0; + } - return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, - qstate->prefetch_leeway, 0, NULL, qstate->query_flags); + return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, + qstate->prefetch_leeway, 0, NULL, qstate->query_flags); } -/* Invalidate the message associated with query_info stored in message cache */ -void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo) -{ - hashvalue_type h; - struct lruhash_entry* e; - struct reply_info *r; - size_t i, j; +/* Invalidate the message associated with query_info stored in message cache */ +void invalidateQueryInCache(struct module_qstate* qstate, + struct query_info* qinfo) +{ + hashvalue_type h; + struct lruhash_entry* e; + struct reply_info *r; + size_t i, j; - h = query_info_hash(qinfo, qstate->query_flags); - if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0))) - { - r = (struct reply_info*)(e->data); - if (r) - { - r->ttl = 0; - if(rrset_array_lock(r->ref, r->rrset_count, *qstate->env->now)) { - for(i=0; i< r->rrset_count; i++) - { - struct packed_rrset_data* data = - (struct packed_rrset_data*) r->ref[i].key->entry.data; - if(i>0 && r->ref[i].key == r->ref[i-1].key) - continue; - - data->ttl = r->ttl; - for(j=0; jcount + data->rrsig_count; j++) - data->rr_ttl[j] = r->ttl; - } - rrset_array_unlock(r->ref, r->rrset_count); - } + h = query_info_hash(qinfo, qstate->query_flags); + if ((e=slabhash_lookup(qstate->env->msg_cache, h, qinfo, 0))) { + r = (struct reply_info*)(e->data); + if (r) { + r->ttl = 0; + if(rrset_array_lock(r->ref, r->rrset_count, *qstate->env->now)) { + for(i=0; i< r->rrset_count; i++) { + struct packed_rrset_data* data = + (struct packed_rrset_data*) r->ref[i].key->entry.data; + if(i>0 && r->ref[i].key == r->ref[i-1].key) + continue; + + data->ttl = r->ttl; + for(j=0; jcount + data->rrsig_count; j++) + data->rr_ttl[j] = r->ttl; + } + rrset_array_unlock(r->ref, r->rrset_count); + } + } + lock_rw_unlock(&e->lock); + } else { + log_info("invalidateQueryInCache: qinfo is not in cache"); } - lock_rw_unlock(&e->lock); - } else { - log_info("invalidateQueryInCache: qinfo is not in cache"); - } } /* Create response according to the ldns packet content */ int createResponse(struct module_qstate* qstate, sldns_buffer* pkt) { - struct msg_parse* prs; - struct edns_data edns; - - /* parse message */ - prs = (struct msg_parse*) regional_alloc(qstate->env->scratch, sizeof(struct msg_parse)); - if (!prs) { - log_err("storeResponse: out of memory on incoming message"); - return 0; - } + struct msg_parse* prs; + struct edns_data edns; - memset(prs, 0, sizeof(*prs)); - memset(&edns, 0, sizeof(edns)); + /* parse message */ + prs = (struct msg_parse*) regional_alloc(qstate->env->scratch, + sizeof(struct msg_parse)); + if(!prs) { + log_err("createResponse: out of memory on incoming message"); + return 0; + } - sldns_buffer_set_position(pkt, 0); - if (parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) { - verbose(VERB_ALGO, "storeResponse: parse error on reply packet"); - return 0; - } - /* edns is not examined, but removed from message to help cache */ - if(parse_extract_edns(prs, &edns, qstate->env->scratch) != - LDNS_RCODE_NOERROR) - return 0; + memset(prs, 0, sizeof(*prs)); + memset(&edns, 0, sizeof(edns)); - /* remove CD-bit, we asked for in case we handle validation ourself */ - prs->flags &= ~BIT_CD; + sldns_buffer_set_position(pkt, 0); + if(parse_packet(pkt, prs, qstate->env->scratch) != LDNS_RCODE_NOERROR) { + verbose(VERB_ALGO, "createResponse: parse error on reply packet"); + return 0; + } + /* edns is not examined, but removed from message to help cache */ + if(parse_extract_edns(prs, &edns, qstate->env->scratch) != + LDNS_RCODE_NOERROR) + return 0; - /* allocate response dns_msg in region */ - qstate->return_msg = (struct dns_msg*)regional_alloc(qstate->region, sizeof(struct dns_msg)); - if (!qstate->return_msg) - return 0; + /* remove CD-bit, we asked for in case we handle validation ourself */ + prs->flags &= ~BIT_CD; - memset(qstate->return_msg, 0, sizeof(*qstate->return_msg)); - if(!parse_create_msg(pkt, prs, NULL, &(qstate->return_msg)->qinfo, &(qstate->return_msg)->rep, qstate->region)) { - log_err("storeResponse: malloc failure: allocating incoming dns_msg"); - return 0; - } - - /* Make sure that the RA flag is set (since the presence of - * this module means that recursion is available) */ - /* qstate->return_msg->rep->flags |= BIT_RA; */ + /* allocate response dns_msg in region */ + qstate->return_msg = (struct dns_msg*) regional_alloc(qstate->region, + sizeof(struct dns_msg)); + if(!qstate->return_msg) + return 0; - /* Clear the AA flag */ - /* FIXME: does this action go here or in some other module? */ - /*qstate->return_msg->rep->flags &= ~BIT_AA; */ + memset(qstate->return_msg, 0, sizeof(*qstate->return_msg)); + if(!parse_create_msg(pkt, prs, NULL, &(qstate->return_msg)->qinfo, + &(qstate->return_msg)->rep, qstate->region)) { + log_err("createResponse: malloc failure: allocating incoming dns_msg"); + return 0; + } - /* make sure QR flag is on */ - /*qstate->return_msg->rep->flags |= BIT_QR; */ + /* Make sure that the RA flag is set (since the presence of + * this module means that recursion is available) */ + /* qstate->return_msg->rep->flags |= BIT_RA; */ - if(verbosity >= VERB_ALGO) - log_dns_msg("storeResponse: packet:", &qstate->return_msg->qinfo, qstate->return_msg->rep); + /* Clear the AA flag */ + /* FIXME: does this action go here or in some other module? */ + /*qstate->return_msg->rep->flags &= ~BIT_AA; */ - return 1; + /* make sure QR flag is on */ + /*qstate->return_msg->rep->flags |= BIT_QR; */ + + if(verbosity >= VERB_ALGO) + log_dns_msg("createResponse: packet:", &qstate->return_msg->qinfo, + qstate->return_msg->rep); + + return 1; } @@ -176,7 +181,7 @@ void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen) sinaddr = &((struct sockaddr_in6*)&(reply->addr))->sin6_addr; dest[0] = 0; if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0) - return; + return; dest[maxlen-1] = 0; } @@ -190,6 +195,6 @@ void delegpt_addr_addr2str(struct delegpt_addr* target, char *dest, int maxlen) sinaddr = &((struct sockaddr_in6*)&(target->addr))->sin6_addr; dest[0] = 0; if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0) - return; + return; dest[maxlen-1] = 0; } diff --git a/pythonmod/pythonmod_utils.h b/pythonmod/pythonmod_utils.h index 4ea86f9be..3fb0c0d7f 100644 --- a/pythonmod/pythonmod_utils.h +++ b/pythonmod/pythonmod_utils.h @@ -1,22 +1,22 @@ /* * pythonmod_utils.h: utils header file - * + * * Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz) * Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz) * * This software is open source. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * * Neither the name of the organization nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. @@ -46,34 +46,38 @@ struct delegpt_addr; struct sldns_buffer; /** - * Store the reply_info and query_info pair in message cache (qstate->msg_cache) + * Store the reply_info and query_info pair in message cache + * (qstate->msg_cache). * * @param qstate: module environment * @param qinfo: query info, the query for which answer is stored. * @param msgrep: reply in dns_msg * @param is_referral: If true, then the given message to be stored is a - * referral. The cache implementation may use this as a hint. - * It will store only the RRsets, not the message. + * referral. The cache implementation may use this as a hint. + * It will store only the RRsets, not the message. * @return 0 on alloc error (out of memory). */ -int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, struct reply_info* msgrep, int is_referral); +int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, + struct reply_info* msgrep, int is_referral); /** - * Invalidate the message associated with query_info stored in message cache. + * Invalidate the message associated with query_info stored in message cache. * - * This function invalidates the record in message cache associated with the given query only if such a record exists. + * This function invalidates the record in message cache associated with the + * given query only if such a record exists. * * @param qstate: module environment * @param qinfo: query info, the query for which answer is stored. */ -void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qinfo); +void invalidateQueryInCache(struct module_qstate* qstate, + struct query_info* qinfo); /** - * Create response according to the ldns packet content + * Create response according to the ldns packet content. + * + * This function fills qstate.return_msg up with data of a given packet * - * This function fills qstate.return_msg up with data of a given packet - * * @param qstate: module environment * @param pkt: a sldns_buffer which contains sldns_packet data * @return 0 on failure, out of memory or parse error. @@ -81,14 +85,20 @@ void invalidateQueryInCache(struct module_qstate* qstate, struct query_info* qin int createResponse(struct module_qstate* qstate, struct sldns_buffer* pkt); /** - * Convert reply->addr to string - * @param reply: comm reply with address in it. - * @param dest: destination string. - * @param maxlen: length of string buffer. + * Convert reply->addr to string. + * @param reply: comm reply with address in it. + * @param dest: destination string. + * @param maxlen: length of string buffer. */ void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen); -/* Convert target->addr to string */ -void delegpt_addr_addr2str(struct delegpt_addr* target, char *dest, int maxlen); +/** + * Convert target->addr to string. + * @param target: delegpt_addr with address in it. + * @param dest: destination string. + * @param maxlen: length of string buffer. + */ +void delegpt_addr_addr2str(struct delegpt_addr* target, char *dest, + int maxlen); #endif /* PYTHONMOD_UTILS_H */ diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index b8c04a3ec..81a7856eb 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -1166,6 +1166,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, &noip6, rcv, snd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { + freeaddrinfo(ub_sock->addr); free(ub_sock); if(noip6) { log_warn("IPv6 protocol not available"); @@ -1176,12 +1177,14 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, /* getting source addr packet info is highly non-portable */ if(!set_recvpktinfo(s, hints->ai_family)) { sock_close(s); + freeaddrinfo(ub_sock->addr); free(ub_sock); return 0; } if(!port_insert(list, s, is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil, ub_sock)) { sock_close(s); + freeaddrinfo(ub_sock->addr); free(ub_sock); return 0; } @@ -1193,6 +1196,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, &noip6, rcv, snd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { + freeaddrinfo(ub_sock->addr); free(ub_sock); if(noip6) { log_warn("IPv6 protocol not available"); @@ -1203,6 +1207,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if(!port_insert(list, s, is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp, ub_sock)) { sock_close(s); + freeaddrinfo(ub_sock->addr); free(ub_sock); return 0; } @@ -1225,6 +1230,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1, &noip6, 0, 0, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock)) == -1) { + freeaddrinfo(ub_sock->addr); free(ub_sock); if(noip6) { /*log_warn("IPv6 protocol not available");*/ @@ -1236,6 +1242,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, verbose(VERB_ALGO, "setup TCP for SSL service"); if(!port_insert(list, s, port_type, ub_sock)) { sock_close(s); + freeaddrinfo(ub_sock->addr); free(ub_sock); return 0; } @@ -1579,7 +1586,7 @@ int resolve_interface_names(char** ifs, int num_ifs, } *num_resif = num_ifs; for(p = list; p; p = p->next) { - *num_resif ++; + (*num_resif)++; } *resif = calloc(*num_resif, sizeof(**resif)); if(!*resif) { @@ -1600,15 +1607,17 @@ int resolve_interface_names(char** ifs, int num_ifs, } } if(list) { + int idx = num_ifs; for(p = list; p; p = p->next) { - (*resif)[i] = strdup(p->str); - if(!((*resif)[i])) { + (*resif)[idx] = strdup(p->str); + if(!((*resif)[idx])) { log_err("out of memory"); config_del_strarray(*resif, *num_resif); *resif = NULL; *num_resif = 0; return 0; } + idx++; } } return 1; diff --git a/services/rpz.c b/services/rpz.c index f61225e03..2ab62581a 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -578,8 +578,10 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, rrtype == LDNS_RR_TYPE_NSEC || rrtype == LDNS_RR_TYPE_NSEC3PARAM || rrtype == LDNS_RR_TYPE_NSEC3 || - rrtype == LDNS_RR_TYPE_DS) + rrtype == LDNS_RR_TYPE_DS) { + free(dname); return; /* no need to log these types as unsupported */ + } dname_str(dname, str); verbose(VERB_ALGO, "RPZ: qname trigger, %s skipping unsupported action: %s", str, rpz_action_to_string(a)); diff --git a/util/iana_ports.inc b/util/iana_ports.inc index 82bbc867b..60bf59115 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -4736,6 +4736,7 @@ 8006, 8007, 8008, +8017, 8019, 8020, 8021, diff --git a/util/netevent.c b/util/netevent.c index 6ef84133b..a5ea46229 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -1633,6 +1633,10 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok) if(errno == ECONNRESET && verbosity < 2) return 0; /* silence reset by peer */ #endif +#ifdef ECONNREFUSED + if(errno == ECONNREFUSED && verbosity < 2) + return 0; /* silence reset by peer */ +#endif #ifdef ENETUNREACH if(errno == ENETUNREACH && verbosity < 2) return 0; /* silence it */ @@ -1661,6 +1665,16 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok) } #endif #else /* USE_WINSOCK */ + if(WSAGetLastError() == WSAECONNREFUSED && verbosity < 2) + return 0; + if(WSAGetLastError() == WSAEHOSTDOWN && verbosity < 2) + return 0; + if(WSAGetLastError() == WSAEHOSTUNREACH && verbosity < 2) + return 0; + if(WSAGetLastError() == WSAENETDOWN && verbosity < 2) + return 0; + if(WSAGetLastError() == WSAENETUNREACH && verbosity < 2) + return 0; if(WSAGetLastError() == WSAECONNRESET) return 0; if(WSAGetLastError() == WSAEINPROGRESS) @@ -2387,7 +2401,7 @@ http_process_chunk_header(struct comm_point* c) return 1; } -/** handle nonchunked data segment */ +/** handle nonchunked data segment, 0=fail, 1=wait */ static int http_nonchunk_segment(struct comm_point* c) { @@ -2396,7 +2410,7 @@ http_nonchunk_segment(struct comm_point* c) * we are looking to read tcp_byte_count more data * and then the transfer is done. */ size_t remainbufferlen; - size_t got_now = sldns_buffer_limit(c->buffer) - c->http_stored; + size_t got_now = sldns_buffer_limit(c->buffer); if(c->tcp_byte_count <= got_now) { /* done, this is the last data fragment */ c->http_stored = 0; @@ -2405,7 +2419,6 @@ http_nonchunk_segment(struct comm_point* c) (void)(*c->callback)(c, c->cb_arg, NETEVENT_DONE, NULL); return 1; } - c->tcp_byte_count -= got_now; /* if we have the buffer space, * read more data collected into the buffer */ remainbufferlen = sldns_buffer_capacity(c->buffer) - @@ -2421,6 +2434,7 @@ http_nonchunk_segment(struct comm_point* c) } /* call callback with this data amount, then * wait for more */ + c->tcp_byte_count -= got_now; c->http_stored = 0; sldns_buffer_set_position(c->buffer, 0); fptr_ok(fptr_whitelist_comm_point(c->callback));