diff --git a/CHANGES b/CHANGES index ba6adf2a49..91462d32d3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,8 @@ --- 9.11.0rc1 released --- +4460. [test] Add system test for dnstap using unix domain sockets. + [RT #42926] + 4459. [bug] TCP client objects created to handle pipeline queries were not cleaned up correctly, causing uncontrolled memory growth. [RT #43106] diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index fa027f701d..a2cc4f2400 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -53,6 +53,7 @@ NSLOOKUP=$TOP/bin/dig/nslookup DNSTAPREAD="$TOP/bin/tools/dnstap-read" MDIG="$TOP/bin/tools/mdig" NZD2NZF="$TOP/bin/tools/named-nzd2nzf" +FSTRM_CAPTURE=@FSTRM_CAPTURE@ RANDFILE=$TOP/bin/tests/system/random.data @@ -118,5 +119,5 @@ NZD=@NZD_TOOLS@ export NAMED LWRESD DIG NSUPDATE KEYGEN KEYFRLAB SIGNER KEYSIGNER KEYSETTOOL \ PERL SUBDIRS RNDC CHECKZONE PK11GEN PK11LIST PK11DEL TESTSOCK6 \ JOURNALPRINT ARPANAME RESOLVE RRCHECKER NSLOOKUP DESCRIPTION PYTHON \ - MDIG + MDIG FSTRM_CAPTURE NZD2NZF diff --git a/bin/tests/system/dnstap/clean.sh b/bin/tests/system/dnstap/clean.sh index 0244b0523f..340338d6d1 100644 --- a/bin/tests/system/dnstap/clean.sh +++ b/bin/tests/system/dnstap/clean.sh @@ -10,7 +10,10 @@ rm -f */named.memstats rm -f */named.run rm -f */named.stats rm -f dig.out* -rm -f ns*/named.lock +rm -f dnstap.out +rm -f dnstap.out.save +rm -f fstrm_capture.out rm -f ns*/dnstap.out rm -f ns*/dnstap.out.save rm -f ns*/dnstap.out.save.? +rm -f ns*/named.lock diff --git a/bin/tests/system/dnstap/ns4/named.conf b/bin/tests/system/dnstap/ns4/named.conf new file mode 100644 index 0000000000..daaf44e57d --- /dev/null +++ b/bin/tests/system/dnstap/ns4/named.conf @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015, 2016 Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +controls { /* empty */ }; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + directory "."; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnstap-identity "ns4"; + dnstap-version "xxx"; + dnstap-output unix "dnstap.out"; + dnstap { all; }; + send-cookie no; + require-server-cookie no; +}; + +server 10.53.0.1 { tcp-only yes; }; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../common/root.hint"; +}; diff --git a/bin/tests/system/dnstap/tests.sh b/bin/tests/system/dnstap/tests.sh index dd76f7b768..78e15e11af 100644 --- a/bin/tests/system/dnstap/tests.sh +++ b/bin/tests/system/dnstap/tests.sh @@ -38,9 +38,16 @@ $DIG +short @10.53.0.3 -p 5300 a.example > dig.out mv ns1/dnstap.out ns1/dnstap.out.save mv ns2/dnstap.out ns2/dnstap.out.save +if [ -n "$FSTRM_CAPTURE" ] ; then + $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \ + -w dnstap.out >& fstrm_capture.out & + fstrm_capture_pid=$! +fi + $RNDCCMD -s 10.53.0.1 dnstap-reopen | sed 's/^/I:ns1 /' $RNDCCMD -s 10.53.0.2 dnstap -reopen | sed 's/^/I:ns2 /' $RNDCCMD -s 10.53.0.3 dnstap -roll | sed 's/^/I:ns3 /' +$RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/I:ns4 /' $DIG +short @10.53.0.3 -p 5300 a.example > dig.out @@ -337,5 +344,166 @@ ret=0 if [ $ret != 0 ]; then echo "I: failed"; fi status=`expr $status + $ret` + +if [ -n "$FSTRM_CAPTURE" ] ; then + $DIG +short @10.53.0.4 -p 5300 a.example > dig.out + + echo "I:checking unix socket message counts" + sleep 2 + kill $fstrm_capture_pid + wait + udp4=`$DNSTAPREAD dnstap.out | grep "UDP " | wc -l` + tcp4=`$DNSTAPREAD dnstap.out | grep "TCP " | wc -l` + aq4=`$DNSTAPREAD dnstap.out | grep "AQ " | wc -l` + ar4=`$DNSTAPREAD dnstap.out | grep "AR " | wc -l` + cq4=`$DNSTAPREAD dnstap.out | grep "CQ " | wc -l` + cr4=`$DNSTAPREAD dnstap.out | grep "CR " | wc -l` + rq4=`$DNSTAPREAD dnstap.out | grep "RQ " | wc -l` + rr4=`$DNSTAPREAD dnstap.out | grep "RR " | wc -l` + + echo "I: checking UDP message counts" + ret=0 + [ $udp4 -eq 2 ] || { + echo "ns4 $udp4 expected 2" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking TCP message counts" + ret=0 + [ $tcp4 -eq 0 ] || { + echo "ns4 $tcp4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking AUTH_QUERY message counts" + ret=0 + [ $aq4 -eq 0 ] || { + echo "ns4 $aq4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking AUTH_RESPONSE message counts" + ret=0 + [ $ar4 -eq 0 ] || { + echo "ns4 $ar4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking CLIENT_QUERY message counts" + ret=0 + [ $cq4 -eq 1 ] || { + echo "ns4 $cq4 expected 1" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking CLIENT_RESPONSE message counts" + ret=0 + [ $cr4 -eq 1 ] || { + echo "ns4 $cr4 expected 1" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking RESOLVER_QUERY message counts" + ret=0 + [ $rq4 -eq 0 ] || { + echo "ns4 $rq4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking RESOLVER_RESPONSE message counts" + ret=0 + [ $rr4 -eq 0 ] || { + echo "ns4 $rr4 expected 0" ; ret=1 + } + mv dnstap.out dnstap.out.save + $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \ + -w dnstap.out >& fstrm_capture.out & + fstrm_capture_pid=$! + $RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/I:ns4 /' + $DIG +short @10.53.0.4 -p 5300 a.example > dig.out + + echo "I:checking reopened unix socket message counts" + sleep 2 + kill $fstrm_capture_pid + wait + udp4=`$DNSTAPREAD dnstap.out | grep "UDP " | wc -l` + tcp4=`$DNSTAPREAD dnstap.out | grep "TCP " | wc -l` + aq4=`$DNSTAPREAD dnstap.out | grep "AQ " | wc -l` + ar4=`$DNSTAPREAD dnstap.out | grep "AR " | wc -l` + cq4=`$DNSTAPREAD dnstap.out | grep "CQ " | wc -l` + cr4=`$DNSTAPREAD dnstap.out | grep "CR " | wc -l` + rq4=`$DNSTAPREAD dnstap.out | grep "RQ " | wc -l` + rr4=`$DNSTAPREAD dnstap.out | grep "RR " | wc -l` + + echo "I: checking UDP message counts" + ret=0 + [ $udp4 -eq 2 ] || { + echo "ns4 $udp4 expected 2" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking TCP message counts" + ret=0 + [ $tcp4 -eq 0 ] || { + echo "ns4 $tcp4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking AUTH_QUERY message counts" + ret=0 + [ $aq4 -eq 0 ] || { + echo "ns4 $aq4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking AUTH_RESPONSE message counts" + ret=0 + [ $ar4 -eq 0 ] || { + echo "ns4 $ar4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking CLIENT_QUERY message counts" + ret=0 + [ $cq4 -eq 1 ] || { + echo "ns4 $cq4 expected 1" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking CLIENT_RESPONSE message counts" + ret=0 + [ $cr4 -eq 1 ] || { + echo "ns4 $cr4 expected 1" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking RESOLVER_QUERY message counts" + ret=0 + [ $rq4 -eq 0 ] || { + echo "ns4 $rq4 expected 0" ; ret=1 + } + if [ $ret != 0 ]; then echo "I: failed"; fi + status=`expr $status + $ret` + + echo "I: checking RESOLVER_RESPONSE message counts" + ret=0 + [ $rr4 -eq 0 ] || { + echo "ns4 $rr4 expected 0" ; ret=1 + } +fi + echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/configure b/configure index b23f42ad9a..56ee93248d 100755 --- a/configure +++ b/configure @@ -704,6 +704,7 @@ DNSTAPOBJS DNSTAPSRCS DNSTAP PROTOC_C +FSTRM_CAPTURE ISC_PLATFORM_BUSYWAITNOP ISC_ARCH_DIR ISC_PLATFORM_USEMACASM @@ -20632,6 +20633,46 @@ esac # # Activate dnstap? # +# Extract the first word of "fstrm_capture", so it can be a program name with args. +set dummy fstrm_capture; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_FSTRM_CAPTURE+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $FSTRM_CAPTURE in + [\\/]* | ?:[\\/]*) + ac_cv_path_FSTRM_CAPTURE="$FSTRM_CAPTURE" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_FSTRM_CAPTURE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +FSTRM_CAPTURE=$ac_cv_path_FSTRM_CAPTURE +if test -n "$FSTRM_CAPTURE"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $FSTRM_CAPTURE" >&5 +$as_echo "$FSTRM_CAPTURE" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + # Check whether --enable-dnstap was given. if test "${enable_dnstap+set}" = set; then : enableval=$enable_dnstap; use_dnstap=$enableval diff --git a/configure.in b/configure.in index 649c2d7df0..2054d3fb6a 100644 --- a/configure.in +++ b/configure.in @@ -4257,6 +4257,7 @@ esac # # Activate dnstap? # +AC_PATH_PROG(FSTRM_CAPTURE, fstrm_capture) AC_ARG_ENABLE(dnstap, [ --enable-dnstap enable dnstap support (requires fstrm, protobuf-c)], use_dnstap=$enableval,