diff --git a/CHANGES b/CHANGES index 799faaf44a..4252c5c40c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +5040. [func] Extended dnstap so that it can log UPDATE requests + and responses as separate message types. Thanks + to Greg Rabil. [GL #570] + 5039. [bug] Named could fail to preserve owner name case of new RRset. [GL #420] diff --git a/bin/named/named.conf.docbook b/bin/named/named.conf.docbook index 0a6c7bde3e..04fc8476a8 100644 --- a/bin/named/named.conf.docbook +++ b/bin/named/named.conf.docbook @@ -13,7 +13,7 @@ - 2018-06-21 + 2018-09-04 ISC @@ -192,6 +192,7 @@ options { ] [ dscp integer ]; alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] [ dscp integer ]; + answer-cookie boolean; attach-cache string; auth-nxdomain boolean; // default changed auto-dnssec ( allow | maintain | off ); @@ -257,8 +258,8 @@ options { dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | - response ) ]; ... }; + dnstap { ( all | auth | client | forwarder | resolver | update ) [ + ( query | response ) ]; ... }; dnstap-identity ( quoted_string | none | hostname ); dnstap-output ( file | unix ) quoted_string [ size ( unlimited | size ) ] [ versions ( unlimited | integer ) ] [ suffix ( @@ -340,6 +341,7 @@ options { min-retry-time integer; minimal-any boolean; minimal-responses ( no-auth | no-auth-recursive | boolean ); + mirror boolean; multi-master boolean; new-zones-directory quoted_string; no-case-compress { address_match_element; ... }; @@ -609,8 +611,8 @@ view string [ class ] { dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | - response ) ]; ... }; + dnstap { ( all | auth | client | forwarder | resolver | update ) [ + ( query | response ) ]; ... }; dual-stack-servers [ port integer ] { ( quoted_string [ port integer ] [ dscp integer ] | ipv4_address [ port integer ] [ dscp integer ] | ipv6_address [ port @@ -671,6 +673,7 @@ view string [ class ] { min-retry-time integer; minimal-any boolean; minimal-responses ( no-auth | no-auth-recursive | boolean ); + mirror boolean; multi-master boolean; new-zones-directory quoted_string; no-case-compress { address_match_element; ... }; @@ -893,10 +896,10 @@ view string [ class ] { static-stub | stub ); update-check-ksk boolean; update-policy ( local | { ( deny | grant ) string ( - 6to4-self | external | krb5-self | krb5-subdomain | - ms-self | ms-subdomain | name | self | selfsub | - selfwild | subdomain | tcp-self | wildcard | zonesub ) - [ string ] rrtypelist; ... }; + 6to4-self | external | krb5-self | krb5-selfsub | + krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | + name | self | selfsub | selfwild | subdomain | tcp-self + | wildcard | zonesub ) [ string ] rrtypelist; ... }; use-alt-transfer-source boolean; zero-no-soa-ttl boolean; zone-statistics ( full | terse | none | boolean ); @@ -996,9 +999,10 @@ zone string [ class ] { forward | hint | redirect | static-stub | stub ); update-check-ksk boolean; update-policy ( local | { ( deny | grant ) string ( 6to4-self | - external | krb5-self | krb5-subdomain | ms-self | ms-subdomain - | name | self | selfsub | selfwild | subdomain | tcp-self | - wildcard | zonesub ) [ string ] rrtypelist; ... }; + external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self + | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild + | subdomain | tcp-self | wildcard | zonesub ) [ string ] + rrtypelist; ... }; use-alt-transfer-source boolean; zero-no-soa-ttl boolean; zone-statistics ( full | terse | none | boolean ); diff --git a/bin/named/server.c b/bin/named/server.c index 8acdae9a26..9052672e2b 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -3412,11 +3412,14 @@ configure_dnstap(const cfg_obj_t **maps, dns_view_t *view) { dt |= DNS_DTTYPE_RQ|DNS_DTTYPE_RR; } else if (strcasecmp(str, "forwarder") == 0) { dt |= DNS_DTTYPE_FQ|DNS_DTTYPE_FR; + } else if (strcasecmp(str, "update") == 0) { + dt |= DNS_DTTYPE_UQ|DNS_DTTYPE_UR; } else if (strcasecmp(str, "all") == 0) { dt |= DNS_DTTYPE_CQ|DNS_DTTYPE_CR| DNS_DTTYPE_AQ|DNS_DTTYPE_AR| DNS_DTTYPE_RQ|DNS_DTTYPE_RR| - DNS_DTTYPE_FQ|DNS_DTTYPE_FR; + DNS_DTTYPE_FQ|DNS_DTTYPE_FR| + DNS_DTTYPE_UQ|DNS_DTTYPE_UR; } obj2 = cfg_tuple_get(obj, "mode"); diff --git a/bin/tests/system/dnstap/clean.sh b/bin/tests/system/dnstap/clean.sh index 699916985c..3faed40d43 100644 --- a/bin/tests/system/dnstap/clean.sh +++ b/bin/tests/system/dnstap/clean.sh @@ -23,3 +23,4 @@ rm -f ns*/dnstap.out.save.? rm -f ns*/named.lock rm -f ydump.out rm -f ns*/managed-keys.bind* +rm -f ns2/example.db ns2/example.db.jnl diff --git a/bin/tests/system/dnstap/ns2/example.db b/bin/tests/system/dnstap/ns2/example.db.in similarity index 100% rename from bin/tests/system/dnstap/ns2/example.db rename to bin/tests/system/dnstap/ns2/example.db.in diff --git a/bin/tests/system/dnstap/setup.sh b/bin/tests/system/dnstap/setup.sh index 3a14fe9e3a..689db2e420 100644 --- a/bin/tests/system/dnstap/setup.sh +++ b/bin/tests/system/dnstap/setup.sh @@ -17,3 +17,5 @@ copy_setports ns1/named.conf.in ns1/named.conf copy_setports ns2/named.conf.in ns2/named.conf copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf + +cp ns2/example.db.in ns2/example.db diff --git a/bin/tests/system/dnstap/tests.sh b/bin/tests/system/dnstap/tests.sh index 14f39b3c6a..28e67f7c99 100644 --- a/bin/tests/system/dnstap/tests.sh +++ b/bin/tests/system/dnstap/tests.sh @@ -55,6 +55,14 @@ $RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/ns4 /' | cat_i $DIG $DIGOPTS @10.53.0.3 a.example > dig.out +# send an UPDATE to ns2 +$NSUPDATE <<- EOF +server 10.53.0.2 ${PORT} +zone example +update add b.example 3600 in a 10.10.10.10 +send +EOF + # XXX: file output should be flushed once a second according # to the libfstrm source, but it doesn't seem to happen until # enough data has accumulated. to get all the output, we stop @@ -75,6 +83,8 @@ cq1=`$DNSTAPREAD ns1/dnstap.out.save | grep "CQ " | wc -l` cr1=`$DNSTAPREAD ns1/dnstap.out.save | grep "CR " | wc -l` rq1=`$DNSTAPREAD ns1/dnstap.out.save | grep "RQ " | wc -l` rr1=`$DNSTAPREAD ns1/dnstap.out.save | grep "RR " | wc -l` +uq1=`$DNSTAPREAD ns1/dnstap.out.save | grep "UQ " | wc -l` +ur1=`$DNSTAPREAD ns1/dnstap.out.save | grep "UR " | wc -l` udp2=`$DNSTAPREAD ns2/dnstap.out.save | grep "UDP " | wc -l` tcp2=`$DNSTAPREAD ns2/dnstap.out.save | grep "TCP " | wc -l` @@ -84,6 +94,8 @@ cq2=`$DNSTAPREAD ns2/dnstap.out.save | grep "CQ " | wc -l` cr2=`$DNSTAPREAD ns2/dnstap.out.save | grep "CR " | wc -l` rq2=`$DNSTAPREAD ns2/dnstap.out.save | grep "RQ " | wc -l` rr2=`$DNSTAPREAD ns2/dnstap.out.save | grep "RR " | wc -l` +uq2=`$DNSTAPREAD ns2/dnstap.out.save | grep "UQ " | wc -l` +ur2=`$DNSTAPREAD ns2/dnstap.out.save | grep "UR " | wc -l` mv ns3/dnstap.out.0 ns3/dnstap.out.save udp3=`$DNSTAPREAD ns3/dnstap.out.save | grep "UDP " | wc -l` @@ -94,6 +106,8 @@ cq3=`$DNSTAPREAD ns3/dnstap.out.save | grep "CQ " | wc -l` cr3=`$DNSTAPREAD ns3/dnstap.out.save | grep "CR " | wc -l` rq3=`$DNSTAPREAD ns3/dnstap.out.save | grep "RQ " | wc -l` rr3=`$DNSTAPREAD ns3/dnstap.out.save | grep "RR " | wc -l` +uq3=`$DNSTAPREAD ns3/dnstap.out.save | grep "UQ " | wc -l` +ur3=`$DNSTAPREAD ns3/dnstap.out.save | grep "UR " | wc -l` echo_i "checking UDP message counts" ret=0 @@ -231,6 +245,40 @@ ret=0 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +echo_i "checking UPDATE_QUERY message counts" +ret=0 +[ $uq1 -eq 0 ] || { + echo_i "ns1 $uq1 expected 0" + ret=1 +} +[ $uq2 -eq 0 ] || { + echo_i "ns2 $uq2 expected 0" + ret=1 +} +[ $uq3 -eq 0 ] || { + echo_i "ns3 $uq3 expected 0" + ret=1 +} +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +echo_i "checking UPDATE_RESPONSE message counts" +ret=0 +[ $ur1 -eq 0 ] || { + echo_i "ns1 $ur1 expected 0" + ret=1 +} +[ $ur2 -eq 0 ] || { + echo_i "ns2 $ur2 expected 0" + ret=1 +} +[ $ur3 -eq 0 ] || { + echo_i "ns3 $ur3 expected 0" + ret=1 +} +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + echo_i "checking reopened message counts" udp1=`$DNSTAPREAD ns1/dnstap.out | grep "UDP " | wc -l` @@ -241,6 +289,8 @@ cq1=`$DNSTAPREAD ns1/dnstap.out | grep "CQ " | wc -l` cr1=`$DNSTAPREAD ns1/dnstap.out | grep "CR " | wc -l` rq1=`$DNSTAPREAD ns1/dnstap.out | grep "RQ " | wc -l` rr1=`$DNSTAPREAD ns1/dnstap.out | grep "RR " | wc -l` +uq1=`$DNSTAPREAD ns1/dnstap.out | grep "UQ " | wc -l` +ur1=`$DNSTAPREAD ns1/dnstap.out | grep "UR " | wc -l` udp2=`$DNSTAPREAD ns2/dnstap.out | grep "UDP " | wc -l` tcp2=`$DNSTAPREAD ns2/dnstap.out | grep "TCP " | wc -l` @@ -250,6 +300,8 @@ cq2=`$DNSTAPREAD ns2/dnstap.out | grep "CQ " | wc -l` cr2=`$DNSTAPREAD ns2/dnstap.out | grep "CR " | wc -l` rq2=`$DNSTAPREAD ns2/dnstap.out | grep "RQ " | wc -l` rr2=`$DNSTAPREAD ns2/dnstap.out | grep "RR " | wc -l` +uq2=`$DNSTAPREAD ns2/dnstap.out | grep "UQ " | wc -l` +ur2=`$DNSTAPREAD ns2/dnstap.out | grep "UR " | wc -l` udp3=`$DNSTAPREAD ns3/dnstap.out | grep "UDP " | wc -l` tcp3=`$DNSTAPREAD ns3/dnstap.out | grep "TCP " | wc -l` @@ -259,6 +311,8 @@ cq3=`$DNSTAPREAD ns3/dnstap.out | grep "CQ " | wc -l` cr3=`$DNSTAPREAD ns3/dnstap.out | grep "CR " | wc -l` rq3=`$DNSTAPREAD ns3/dnstap.out | grep "RQ " | wc -l` rr3=`$DNSTAPREAD ns3/dnstap.out | grep "RR " | wc -l` +uq3=`$DNSTAPREAD ns3/dnstap.out | grep "UQ " | wc -l` +ur3=`$DNSTAPREAD ns3/dnstap.out | grep "UR " | wc -l` echo_i "checking UDP message counts" ret=0 @@ -266,8 +320,8 @@ ret=0 echo_i "ns1 $udp1 expected 0" ret=1 } -[ $udp2 -eq 0 ] || { - echo_i "ns2 $udp2 expected 0" +[ $udp2 -eq 2 ] || { + echo_i "ns2 $udp2 expected 2" ret=1 } [ $udp3 -eq 2 ] || { @@ -396,6 +450,41 @@ ret=0 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +echo_i "checking UPDATE_QUERY message counts" +ret=0 +[ $uq1 -eq 0 ] || { + echo_i "ns1 $uq1 expected 0" + ret=1 +} +[ $uq2 -eq 1 ] || { + echo_i "ns2 $uq2 expected 1" + ret=1 +} +[ $uq3 -eq 0 ] || { + echo_i "ns3 $uq3 expected 0" + ret=1 +} +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +echo_i "checking UPDATE_RESPONSE message counts" +ret=0 +[ $ur1 -eq 0 ] || { + echo_i "ns1 $ur1 expected 0" + ret=1 +} +[ $ur2 -eq 1 ] || { + echo_i "ns2 $ur2 expected 1" + ret=1 +} +[ $ur3 -eq 0 ] || { + echo_i "ns3 $ur3 expected 0" + ret=1 +} +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + + HAS_PYYAML=0 if [ -n "$PYTHON" ] ; then $PYTHON -c "import yaml" 2> /dev/null && HAS_PYYAML=1 @@ -423,6 +512,15 @@ status=`expr $status + $ret` if [ -n "$FSTRM_CAPTURE" ] ; then $DIG $DIGOPTS @10.53.0.4 a.example > dig.out + # send an UPDATE to ns4 + $NSUPDATE <<- EOF > nsupdate.out 2>&1 + server 10.53.0.4 ${PORT} + zone example + update add b.example 3600 in a 10.10.10.10 + send +EOF + grep "update failed: NOTAUTH" nsupdate.out > /dev/null || ret=1 + echo_i "checking unix socket message counts" sleep 2 kill $fstrm_capture_pid @@ -435,11 +533,13 @@ if [ -n "$FSTRM_CAPTURE" ] ; then cr4=`$DNSTAPREAD dnstap.out | grep "CR " | wc -l` rq4=`$DNSTAPREAD dnstap.out | grep "RQ " | wc -l` rr4=`$DNSTAPREAD dnstap.out | grep "RR " | wc -l` + uq4=`$DNSTAPREAD dnstap.out | grep "UQ " | wc -l` + ur4=`$DNSTAPREAD dnstap.out | grep "UR " | wc -l` echo_i "checking UDP message counts" ret=0 - [ $udp4 -eq 2 ] || { - echo_i "ns4 $udp4 expected 2" + [ $udp4 -eq 4 ] || { + echo_i "ns4 $udp4 expected 4" ret=1 } if [ $ret != 0 ]; then echo_i "failed"; fi @@ -505,7 +605,27 @@ if [ -n "$FSTRM_CAPTURE" ] ; then echo_i "ns4 $rr4 expected 0" ret=1 } + + echo_i "checking UPDATE_QUERY message counts" + ret=0 + [ $uq4 -eq 1 ] || { + echo_i "ns4 $uq4 expected 1" + ret=1 + } + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + + echo_i "checking UPDATE_RESPONSE message counts" + ret=0 + [ $ur4 -eq 1 ] || { + echo_i "ns4 $ur4 expected 1" + ret=1 + } + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + mv dnstap.out dnstap.out.save + $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \ -w dnstap.out > fstrm_capture.out 2>&1 & fstrm_capture_pid=$! @@ -524,6 +644,8 @@ if [ -n "$FSTRM_CAPTURE" ] ; then cr4=`$DNSTAPREAD dnstap.out | grep "CR " | wc -l` rq4=`$DNSTAPREAD dnstap.out | grep "RQ " | wc -l` rr4=`$DNSTAPREAD dnstap.out | grep "RR " | wc -l` + uq4=`$DNSTAPREAD dnstap.out | grep "UQ " | wc -l` + ur4=`$DNSTAPREAD dnstap.out | grep "UR " | wc -l` echo_i "checking UDP message counts" ret=0 @@ -594,6 +716,24 @@ if [ -n "$FSTRM_CAPTURE" ] ; then echo_i "ns4 $rr4 expected 0" ret=1 } + + echo_i "checking UPDATE_QUERY message counts" + ret=0 + [ $uq4 -eq 0 ] || { + echo_i "ns4 $uq4 expected 0" + ret=1 + } + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` + + echo_i "checking UPDATE_RESPONSE message counts" + ret=0 + [ $ur4 -eq 0 ] || { + echo_i "ns4 $ur4 expected 0" + ret=1 + } + if [ $ret != 0 ]; then echo_i "failed"; fi + status=`expr $status + $ret` fi echo_i "exit status: $status" diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index f34ac57b6b..c012ce88c7 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -4366,10 +4366,11 @@ badresp:1,adberr:0,findfail:0,valfail:0] The dnstap option is a bracketed list of message types to be logged. These may be set differently for each view. Supported types are client, - auth, resolver, and - forwarder. Specifying type - all will cause all dnstap - messages to be logged, regardless of type. + auth, resolver, + forwarder, and update. + Specifying type all will cause all + dnstap messages to be logged, regardless of + type. Each type may take an additional argument to indicate whether diff --git a/doc/arm/master.zoneopt.xml b/doc/arm/master.zoneopt.xml index e1261b4e9a..d612445880 100644 --- a/doc/arm/master.zoneopt.xml +++ b/doc/arm/master.zoneopt.xml @@ -63,7 +63,7 @@ sig-signing-type integer; sig-validity-interval integer [ integer ]; update-check-ksk boolean; - update-policy ( local | { ( deny | grant ) string ( 6to4-self | external | krb5-self | krb5-subdomain | ms-self | ms-subdomain | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ string ] rrtypelist; ... }; + update-policy ( local | { ( deny | grant ) string ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ string ] rrtypelist; ... }; zero-no-soa-ttl boolean; zone-statistics ( full | terse | none | boolean ); }; diff --git a/doc/arm/options.grammar.xml b/doc/arm/options.grammar.xml index 41c115c4a0..3eae56c229 100644 --- a/doc/arm/options.grammar.xml +++ b/doc/arm/options.grammar.xml @@ -31,6 +31,7 @@ ] [ dscp integer ]; alt-transfer-source-v6 ( ipv6_address | * ) [ port ( integer | * ) ] [ dscp integer ]; + answer-cookie boolean; attach-cache string; auth-nxdomain boolean; // default changed auto-dnssec ( allow | maintain | off ); @@ -96,8 +97,8 @@ dnssec-secure-to-insecure boolean; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | resolver ) [ ( query | - response ) ]; ... }; + dnstap { ( all | auth | client | forwarder | resolver | update ) [ + ( query | response ) ]; ... }; dnstap-identity ( quoted_string | none | hostname ); dnstap-output ( file | unix ) quoted_string [ size ( unlimited | size ) ] [ versions ( unlimited | integer ) ] [ suffix ( diff --git a/doc/misc/master.zoneopt b/doc/misc/master.zoneopt index 42b794de51..12cf216093 100644 --- a/doc/misc/master.zoneopt +++ b/doc/misc/master.zoneopt @@ -51,7 +51,7 @@ zone [ ] { sig-signing-type ; sig-validity-interval [ ]; update-check-ksk ; - update-policy ( local | { ( deny | grant ) ( 6to4-self | external | krb5-self | krb5-subdomain | ms-self | ms-subdomain | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ ] ; ... }; + update-policy ( local | { ( deny | grant ) ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ ] ; ... }; zero-no-soa-ttl ; zone-statistics ( full | terse | none | ); }; diff --git a/doc/misc/options b/doc/misc/options index d0c8310370..546e5144d4 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -146,15 +146,13 @@ options { dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; // not configured - dnstap-identity ( | none | - hostname ); // not configured - dnstap-output ( file | unix ) [ - size ( unlimited | ) ] [ versions ( - unlimited | ) ] [ suffix ( increment - | timestamp ) ]; // not configured - dnstap-version ( | none ); // not configured + dnstap { ( all | auth | client | forwarder | resolver | update ) [ + ( query | response ) ]; ... }; + dnstap-identity ( | none | hostname ); + dnstap-output ( file | unix ) [ size ( unlimited | + ) ] [ versions ( unlimited | ) ] [ suffix ( + increment | timestamp ) ]; + dnstap-version ( | none ); dscp ; dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port @@ -178,14 +176,14 @@ options { forward ( first | only ); forwarders [ port ] [ dscp ] { ( | ) [ port ] [ dscp ]; ... }; - fstrm-set-buffer-hint ; // not configured - fstrm-set-flush-timeout ; // not configured - fstrm-set-input-queue-size ; // not configured - fstrm-set-output-notify-threshold ; // not configured - fstrm-set-output-queue-model ( mpsc | spsc ); // not configured - fstrm-set-output-queue-size ; // not configured - fstrm-set-reopen-interval ; // not configured - geoip-directory ( | none ); // not configured + fstrm-set-buffer-hint ; + fstrm-set-flush-timeout ; + fstrm-set-input-queue-size ; + fstrm-set-output-notify-threshold ; + fstrm-set-output-queue-model ( mpsc | spsc ); + fstrm-set-output-queue-size ; + fstrm-set-reopen-interval ; + geoip-directory ( | none ); geoip-use-ecs ; // obsolete glue-cache ; has-old-clients ; // obsolete @@ -206,7 +204,7 @@ options { listen-on-v6 [ port ] [ dscp ] { ; ... }; // may occur multiple times - lmdb-mapsize ; // non-operational + lmdb-mapsize ; lock-file ( | none ); maintain-ixfr-base ; // obsolete managed-keys-directory ; @@ -515,8 +513,8 @@ view [ ] { dnssec-secure-to-insecure ; dnssec-update-mode ( maintain | no-resign ); dnssec-validation ( yes | no | auto ); - dnstap { ( all | auth | client | forwarder | - resolver ) [ ( query | response ) ]; ... }; // not configured + dnstap { ( all | auth | client | forwarder | resolver | update ) [ + ( query | response ) ]; ... }; dual-stack-servers [ port ] { ( [ port ] [ dscp ] | [ port ] [ dscp ] | [ port @@ -547,7 +545,7 @@ view [ ] { }; // may occur multiple times key-directory ; lame-ttl ; - lmdb-mapsize ; // non-operational + lmdb-mapsize ; maintain-ixfr-base ; // obsolete managed-keys { @@ -822,10 +820,10 @@ view [ ] { static-stub | stub ); update-check-ksk ; update-policy ( local | { ( deny | grant ) ( - 6to4-self | external | krb5-self | krb5-subdomain | - ms-self | ms-subdomain | name | self | selfsub | - selfwild | subdomain | tcp-self | wildcard | zonesub ) - [ ] ; ... }; + 6to4-self | external | krb5-self | krb5-selfsub | + krb5-subdomain | ms-self | ms-selfsub | ms-subdomain | + name | self | selfsub | selfwild | subdomain | tcp-self + | wildcard | zonesub ) [ ] ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; zone-statistics ( full | terse | none | ); @@ -926,9 +924,10 @@ zone [ ] { forward | hint | redirect | static-stub | stub ); update-check-ksk ; update-policy ( local | { ( deny | grant ) ( 6to4-self | - external | krb5-self | krb5-subdomain | ms-self | ms-subdomain - | name | self | selfsub | selfwild | subdomain | tcp-self | - wildcard | zonesub ) [ ] ; ... }; + external | krb5-self | krb5-selfsub | krb5-subdomain | ms-self + | ms-selfsub | ms-subdomain | name | self | selfsub | selfwild + | subdomain | tcp-self | wildcard | zonesub ) [ ] + ; ... }; use-alt-transfer-source ; zero-no-soa-ttl ; zone-statistics ( full | terse | none | ); diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c index 077445d005..cd83d45633 100644 --- a/lib/dns/dnstap.c +++ b/lib/dns/dnstap.c @@ -694,6 +694,10 @@ dnstap_type(dns_dtmsgtype_t msgtype) { return (DNSTAP__MESSAGE__TYPE__TOOL_QUERY); case DNS_DTTYPE_TR: return (DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE); + case DNS_DTTYPE_UQ: + return (DNSTAP__MESSAGE__TYPE__UPDATE_QUERY); + case DNS_DTTYPE_UR: + return (DNSTAP__MESSAGE__TYPE__UPDATE_RESPONSE); default: INSIST(0); } @@ -860,6 +864,7 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, case DNS_DTTYPE_FR: case DNS_DTTYPE_SR: case DNS_DTTYPE_TR: + case DNS_DTTYPE_UR: if (rtime != NULL) t = rtime; @@ -881,6 +886,7 @@ dns_dt_send(dns_view_t *view, dns_dtmsgtype_t msgtype, case DNS_DTTYPE_RQ: case DNS_DTTYPE_SQ: case DNS_DTTYPE_TQ: + case DNS_DTTYPE_UQ: if (qtime != NULL) t = qtime; @@ -1160,6 +1166,12 @@ dns_dt_parse(isc_mem_t *mctx, isc_region_t *src, dns_dtdata_t **destp) { case DNSTAP__MESSAGE__TYPE__TOOL_RESPONSE: d->type = DNS_DTTYPE_TR; break; + case DNSTAP__MESSAGE__TYPE__UPDATE_QUERY: + d->type = DNS_DTTYPE_UQ; + break; + case DNSTAP__MESSAGE__TYPE__UPDATE_RESPONSE: + d->type = DNS_DTTYPE_UR; + break; default: CHECK(DNS_R_BADDNSTAP); } @@ -1316,6 +1328,12 @@ dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest) { case DNS_DTTYPE_TR: CHECK(putstr(dest, "TR ")); break; + case DNS_DTTYPE_UQ: + CHECK(putstr(dest, "UQ ")); + break; + case DNS_DTTYPE_UR: + CHECK(putstr(dest, "UR ")); + break; default: return (DNS_R_BADDNSTAP); } diff --git a/lib/dns/dnstap.proto b/lib/dns/dnstap.proto index 1ed1bb00e2..5280c9b650 100644 --- a/lib/dns/dnstap.proto +++ b/lib/dns/dnstap.proto @@ -165,6 +165,16 @@ message Message { // TOOL_RESPONSE is a DNS response message received by a DNS software // tool from a DNS server, from the perspective of the tool. TOOL_RESPONSE = 12; + + // UPDATE_QUERY is a DNS update query message received from a resolver + // by an authoritative name server, from the perspective of the + // authoritative name server. + UPDATE_QUERY = 13; + + // UPDATE_RESPONSE is a DNS update response message sent from an + // authoritative name server to a resolver, from the perspective of the + // authoritative name server. + UPDATE_RESPONSE = 14; } // One of the Type values described above. diff --git a/lib/dns/include/dns/dnstap.h b/lib/dns/include/dns/dnstap.h index bc3b79e9eb..e27c95e8a0 100644 --- a/lib/dns/include/dns/dnstap.h +++ b/lib/dns/include/dns/dnstap.h @@ -73,13 +73,17 @@ struct fstrm_iothr_options; #define DNS_DTTYPE_FR 0x0200 #define DNS_DTTYPE_TQ 0x0400 #define DNS_DTTYPE_TR 0x0800 +#define DNS_DTTYPE_UQ 0x1000 +#define DNS_DTTYPE_UR 0x2000 #define DNS_DTTYPE_QUERY \ (DNS_DTTYPE_SQ|DNS_DTTYPE_CQ|DNS_DTTYPE_AQ|\ - DNS_DTTYPE_RQ|DNS_DTTYPE_FQ|DNS_DTTYPE_TQ) + DNS_DTTYPE_RQ|DNS_DTTYPE_FQ|DNS_DTTYPE_TQ|\ + DNS_DTTYPE_UQ) #define DNS_DTTYPE_RESPONSE \ (DNS_DTTYPE_SR|DNS_DTTYPE_CR|DNS_DTTYPE_AR|\ - DNS_DTTYPE_RR|DNS_DTTYPE_FR|DNS_DTTYPE_TR) + DNS_DTTYPE_RR|DNS_DTTYPE_FR|DNS_DTTYPE_TR|\ + DNS_DTTYPE_UR) #define DNS_DTTYPE_ALL \ (DNS_DTTYPE_QUERY|DNS_DTTYPE_RESPONSE) diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index c6b1072d88..d6881de77f 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1276,10 +1276,11 @@ static cfg_type_t cfg_type_resppadding = { * ... * } * - * ... where message type is one of: client, resolver, auth, forwarder, all + * ... where message type is one of: client, resolver, auth, forwarder, + * update, all */ static const char *dnstap_types[] = { - "all", "auth", "client", "forwarder", "resolver", NULL + "all", "auth", "client", "forwarder", "resolver", "update", NULL }; static const char *dnstap_modes[] = { "query", "response", NULL }; diff --git a/lib/ns/client.c b/lib/ns/client.c index bcf022e1ee..b5c3175dc2 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -1225,10 +1225,13 @@ client_send(ns_client_t *client) { isc_buffer_usedregion(&b, &zr); } - if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) + if (client->message->opcode == dns_opcode_update) { + dtmsgtype = DNS_DTTYPE_UR; + } else if ((client->message->flags & DNS_MESSAGEFLAG_RD) != 0) { dtmsgtype = DNS_DTTYPE_CR; - else + } else { dtmsgtype = DNS_DTTYPE_AR; + } #endif /* HAVE_DNSTAP */ if (cleanup_cctx) { @@ -1269,9 +1272,11 @@ client_send(ns_client_t *client) { break; } } else { - respsize = isc_buffer_usedlength(&buffer); - result = client_sendpkg(client, &buffer); #ifdef HAVE_DNSTAP + /* + * Log dnstap data first, because client_sendpkg() may + * leave client->view set to NULL. + */ if (client->view != NULL) { dns_dt_send(client->view, dtmsgtype, &client->peeraddr, @@ -1281,6 +1286,9 @@ client_send(ns_client_t *client) { } #endif /* HAVE_DNSTAP */ + respsize = isc_buffer_usedlength(&buffer); + result = client_sendpkg(client, &buffer); + switch (isc_sockaddr_pf(&client->peeraddr)) { case AF_INET: isc_stats_increment(client->sctx->udpoutstats4, @@ -2847,6 +2855,11 @@ ns__client_request(isc_task_t *task, isc_event_t *event) { break; case dns_opcode_update: CTRACE("update"); +#ifdef HAVE_DNSTAP + dns_dt_send(client->view, DNS_DTTYPE_UQ, &client->peeraddr, + &client->destsockaddr, TCP_CLIENT(client), NULL, + &client->requesttime, NULL, buffer); +#endif /* HAVE_DNSTAP */ ns_client_settimeout(client, 60); ns_update_start(client, sigresult); break; diff --git a/util/copyrights b/util/copyrights index bd7e66e020..3d5aa3075d 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1091,7 +1091,7 @@ ./bin/tests/system/dnstap/good-size-version.conf CONF-C 2017,2018 ./bin/tests/system/dnstap/ns1/named.conf.in CONF-C 2015,2016,2017,2018 ./bin/tests/system/dnstap/ns1/root.db ZONE 2015,2016,2018 -./bin/tests/system/dnstap/ns2/example.db ZONE 2015,2016,2018 +./bin/tests/system/dnstap/ns2/example.db.in ZONE 2015,2016,2018 ./bin/tests/system/dnstap/ns2/named.conf.in CONF-C 2015,2016,2017,2018 ./bin/tests/system/dnstap/ns3/named.conf.in CONF-C 2015,2016,2017,2018 ./bin/tests/system/dnstap/ns4/named.conf.in CONF-C 2016,2018