From 553197e28833ed2d8bf26f8112eaa137dbaa040a Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 1 Dec 2011 00:53:58 +0000 Subject: [PATCH] 3231. [bug] named could fail to send a uncompressable zone. [RT #26796] 3230. [bug[ 'dig axfr' failed to properly handle a multi-message axfr with a serial of 0. [RT #26796] --- CHANGES | 6 ++++ bin/dig/dighost.c | 41 +++++++++++------------ bin/named/xfrout.c | 17 ++++++++-- bin/tests/system/xfer/clean.sh | 5 +-- bin/tests/system/xfer/ns4/named.conf.base | 7 +++- bin/tests/system/xfer/ns4/root.db.in | 4 +++ bin/tests/system/xfer/setup.sh | 7 +++- bin/tests/system/xfer/tests.sh | 10 +++++- 8 files changed, 67 insertions(+), 30 deletions(-) create mode 100644 bin/tests/system/xfer/ns4/root.db.in diff --git a/CHANGES b/CHANGES index 234e67f3c9..b8e595b105 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +3231. [bug] named could fail to send a uncompressable zone. + [RT #26796] + +3230. [bug[ 'dig axfr' failed to properly handle a multi-message + axfr with a serial of 0. [RT #26796] + 3229. [bug] Fix local variable to struct var assignment found by CLANG warning. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 4892603d9b..743885b039 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dighost.c,v 1.343 2011/11/30 00:48:51 marka Exp $ */ +/* $Id: dighost.c,v 1.344 2011/12/01 00:53:58 marka Exp $ */ /*! \file * \note @@ -82,6 +82,7 @@ #include #include #include +#include #include #include #include @@ -743,7 +744,7 @@ make_empty_lookup(void) { looknew->xfr_q = NULL; looknew->current_query = NULL; looknew->doing_xfr = ISC_FALSE; - looknew->ixfr_serial = ISC_FALSE; + looknew->ixfr_serial = 0; looknew->trace = ISC_FALSE; looknew->trace_root = ISC_FALSE; looknew->identify = ISC_FALSE; @@ -2869,8 +2870,10 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, dns_rdataset_t *rdataset = NULL; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; - isc_uint32_t serial; + isc_uint32_t ixfr_serial = query->lookup->ixfr_serial, serial; isc_result_t result; + isc_boolean_t ixfr = query->lookup->rdtype == dns_rdatatype_ixfr; + isc_boolean_t axfr = query->lookup->rdtype == dns_rdatatype_axfr; debug("check_for_more_data()"); @@ -2920,6 +2923,7 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, query->second_rr_rcvd = ISC_TRUE; query->second_rr_serial = 0; debug("got the second rr as nonsoa"); + axfr = ISC_TRUE; goto next_rdata; } @@ -2929,6 +2933,7 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, */ if (rdata.type != dns_rdatatype_soa) goto next_rdata; + /* Now we have an SOA. Work with it. */ debug("got an SOA"); result = dns_rdata_tostruct(&rdata, &soa, NULL); @@ -2938,15 +2943,17 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, if (!query->first_soa_rcvd) { query->first_soa_rcvd = ISC_TRUE; query->first_rr_serial = serial; - debug("this is the first %d", - query->lookup->ixfr_serial); - if (query->lookup->ixfr_serial >= - serial) + debug("this is the first serial %u", + serial); + if (ixfr && isc_serial_ge(ixfr_serial, + serial)) { + debug("got up to date " + "response"); goto doexit; + } goto next_rdata; } - if (query->lookup->rdtype == - dns_rdatatype_axfr) { + if (axfr) { debug("doing axfr, got second SOA"); goto doexit; } @@ -2956,22 +2963,12 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, "empty zone"); goto doexit; } - debug("this is the second %d", - query->lookup->ixfr_serial); + debug("this is the second serial %u", + serial); query->second_rr_rcvd = ISC_TRUE; query->second_rr_serial = serial; goto next_rdata; } - if (query->second_rr_serial == 0) { - /* - * If the second RR was a non-SOA - * record, and we're getting any - * other SOA, then this is an - * AXFR, and we're done. - */ - debug("done, since axfr"); - goto doexit; - } /* * If we get to this point, we're doing an * IXFR and have to start really looking @@ -2987,7 +2984,7 @@ check_for_more_data(dig_query_t *query, dns_message_t *msg, debug("done with ixfr"); goto doexit; } - debug("meaningless soa %d", serial); + debug("meaningless soa %u", serial); next_rdata: result = dns_rdataset_next(rdataset); } while (result == ISC_R_SUCCESS); diff --git a/bin/named/xfrout.c b/bin/named/xfrout.c index dc9e69c949..43eec8e899 100644 --- a/bin/named/xfrout.c +++ b/bin/named/xfrout.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrout.c,v 1.142 2011/07/28 04:27:26 marka Exp $ */ +/* $Id: xfrout.c,v 1.143 2011/12/01 00:53:58 marka Exp $ */ #include @@ -1286,6 +1286,13 @@ sendstream(xfrout_ctx_t *xfr) { if (xfr->lasttsig != NULL) isc_buffer_free(&xfr->lasttsig); + /* + * Account for reserved space. + */ + if (xfr->tsigkey != NULL) + INSIST(msg->reserved != 0U); + isc_buffer_add(&xfr->buf, msg->reserved); + /* * Include a question section in the first message only. * BIND 8.2.1 will not recognize an IXFR if it does not @@ -1324,9 +1331,13 @@ sendstream(xfrout_ctx_t *xfr) { ISC_LIST_APPEND(qname->list, qrdataset, link); dns_message_addname(msg, qname, DNS_SECTION_QUESTION); - } - else + } else { + /* + * Reserve space for the 12-byte message header + */ + isc_buffer_add(&xfr->buf, 12); msg->tcp_continuation = 1; + } } /* diff --git a/bin/tests/system/xfer/clean.sh b/bin/tests/system/xfer/clean.sh index e0c19c2b9d..5aa36f373f 100644 --- a/bin/tests/system/xfer/clean.sh +++ b/bin/tests/system/xfer/clean.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.16 2011/03/12 04:59:47 tbox Exp $ +# $Id: clean.sh,v 1.17 2011/12/01 00:53:58 marka Exp $ # # Clean up after zone transfer tests. @@ -23,11 +23,12 @@ rm -f dig.out.ns1 dig.out.ns2 dig.out.ns3 rm -f dig.out.ns5 dig.out.ns6 dig.out.ns7 +rm -f axfr.out rm -f ns1/slave.db rm -f ns2/example.db ns2/tsigzone.db ns2/example.db.jnl rm -f ns3/example.bk ns3/tsigzone.bk ns3/example.bk.jnl rm -f ns3/master.bk ns3/master.bk.jnl -rm -f ns4/named.conf ns4/nil.db +rm -f ns4/named.conf ns4/nil.db ns4/root.db rm -f ns6/*.db ns6/*.bk ns6/*.jnl rm -f ns7/*.db ns7/*.bk ns7/*.jnl diff --git a/bin/tests/system/xfer/ns4/named.conf.base b/bin/tests/system/xfer/ns4/named.conf.base index 98df2295b4..231fcfaef6 100644 --- a/bin/tests/system/xfer/ns4/named.conf.base +++ b/bin/tests/system/xfer/ns4/named.conf.base @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf.base,v 1.2 2011/03/04 22:01:01 each Exp $ */ +/* $Id: named.conf.base,v 1.3 2011/12/01 00:53:58 marka Exp $ */ options { query-source address 10.53.0.4; @@ -46,3 +46,8 @@ key tsig_key. { controls { inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; }; + +zone "." { + type master; + file "root.db"; +}; diff --git a/bin/tests/system/xfer/ns4/root.db.in b/bin/tests/system/xfer/ns4/root.db.in new file mode 100644 index 0000000000..701dd92e67 --- /dev/null +++ b/bin/tests/system/xfer/ns4/root.db.in @@ -0,0 +1,4 @@ +; Copyright +@ 0 SOA . . 0 0 0 0 0 +@ 0 NS . +@ 0 A 10.53.0.4 diff --git a/bin/tests/system/xfer/setup.sh b/bin/tests/system/xfer/setup.sh index 1c5961fea1..8a9be85638 100644 --- a/bin/tests/system/xfer/setup.sh +++ b/bin/tests/system/xfer/setup.sh @@ -15,7 +15,10 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: setup.sh,v 1.8 2011/03/11 00:43:53 marka Exp $ +# $Id: setup.sh,v 1.9 2011/12/01 00:53:58 marka Exp $ + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh sh clean.sh @@ -26,4 +29,6 @@ sh ../genzone.sh 6 3 >ns6/master.db sh ../genzone.sh 7 >ns7/master2.db rm -f ns4/*.db ns4/*.jnl +cp -f ns4/root.db.in ns4/root.db +$PERL -e 'for ($i=0;$i<10000;$i++){ printf("x%u 0 in a 10.53.0.1\n", $i);}' >> ns4/root.db cp -f ns4/named.conf.base ns4/named.conf diff --git a/bin/tests/system/xfer/tests.sh b/bin/tests/system/xfer/tests.sh index ce8eb3e645..a11519dfed 100644 --- a/bin/tests/system/xfer/tests.sh +++ b/bin/tests/system/xfer/tests.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.34 2011/03/11 00:43:53 marka Exp $ +# $Id: tests.sh,v 1.35 2011/12/01 00:53:58 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -201,6 +201,14 @@ test -f ns7/slave.bk.jnl || tmp=1 if test $tmp != 0 ; then echo "I:failed"; fi status=`expr $status + $tmp` +echo "I:check that a multi-message uncompressable zone transfers" +$DIG axfr . -p 5300 @10.53.0.4 | grep SOA > axfr.out +if test `wc -l < axfr.out` != 2 +then + echo "I:failed" + status=`expr $status + 1` +fi + # now we test transfers with assorted TSIG glitches DIGCMD="$DIG $DIGOPTS @10.53.0.4 -p 5300" SENDCMD="$PERL ../send.pl 10.53.0.5 5301"