diff --git a/CHANGES b/CHANGES index 828999d6e5..a50f8c5066 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3013. [bug] The DNS64 ttl was not always being set as expected. + [RT #23034] + 3012. [bug] Remove DNSKEY TTL change pairs before generating signing records for any remaining DNSKEY changes. [RT #22590] diff --git a/bin/named/query.c b/bin/named/query.c index 64a7f3eb97..69d318ea2a 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: query.c,v 1.353 2011/01/13 23:16:06 marka Exp $ */ +/* $Id: query.c,v 1.353.8.1 2011/02/03 07:39:02 marka Exp $ */ /*! \file */ @@ -4847,6 +4847,40 @@ is_v4_client(ns_client_t *client) { } #endif +static isc_uint32_t +dns64_ttl(dns_db_t *db, dns_dbversion_t *version) { + dns_dbnode_t *node = NULL; + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_t rdataset; + isc_result_t result; + isc_uint32_t ttl = ISC_UINT32_MAX; + + result = dns_db_getoriginnode(db, &node); + if (result != ISC_R_SUCCESS) + goto cleanup; + dns_rdataset_init(&rdataset); + result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) + goto cleanup; + result = dns_rdataset_first(&rdataset); + if (result != ISC_R_SUCCESS) + goto cleanup; + + dns_rdataset_current(&rdataset, &rdata); + result = dns_rdata_tostruct(&rdata, &soa, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + ttl = ISC_MIN(rdataset.ttl, soa.minimum); + +cleanup: + if (dns_rdataset_isassociated(&rdataset)) + dns_rdataset_disassociate(&rdataset); + if (node != NULL) + dns_db_detachnode(db, &node); + return (ttl); +} + static isc_boolean_t dns64_aaaaok(ns_client_t *client, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) @@ -5685,6 +5719,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) INSIST(client->query.dns64_sigaaaa == NULL); client->query.dns64_aaaa = rdataset; client->query.dns64_sigaaaa = sigrdataset; + client->query.dns64_ttl = dns64_ttl(db, version); query_releasename(client, &fname); dns_db_detachnode(db, &node); rdataset = NULL; @@ -5935,7 +5970,15 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) INSIST(client->query.dns64_sigaaaa == NULL); client->query.dns64_aaaa = rdataset; client->query.dns64_sigaaaa = sigrdataset; - client->query.dns64_ttl = rdataset->ttl; + /* + * If the ttl is zero we need to workout if we have just + * decremented to zero or if there was no negative cache + * ttl in the answer. + */ + if (rdataset->ttl != 0) + client->query.dns64_ttl = rdataset->ttl; + else if (dns_rdataset_first(rdataset) == ISC_R_SUCCESS) + client->query.dns64_ttl = 0; query_releasename(client, &fname); dns_db_detachnode(db, &node); rdataset = NULL; @@ -6583,7 +6626,7 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype) if (!is_zone) goto cleanup; /* - * Add a fake the SOA record. + * Add a fake SOA record. */ result = query_addsoa(client, db, version, 600, diff --git a/bin/tests/system/dns64/ns1/example.db b/bin/tests/system/dns64/ns1/example.db index 901c0a9e35..3f2f636f74 100644 --- a/bin/tests/system/dns64/ns1/example.db +++ b/bin/tests/system/dns64/ns1/example.db @@ -12,7 +12,7 @@ ; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ; PERFORMANCE OF THIS SOFTWARE. -; $Id: example.db,v 1.3 2010/12/08 23:51:56 tbox Exp $ +; $Id: example.db,v 1.3.22.1 2011/02/03 07:39:02 marka Exp $ $TTL 3600 @ SOA ns1 marka.isc.org. 0 0 0 0 1200 @@ -49,3 +49,7 @@ cname-aaaa-only CNAME aaaa-only cname-a-not-mapped CNAME a-not-mapped cname-mx-only CNAME mx-only cname-non-existent CNAME non-existent +ttl-less-than-600 500 A 5.6.7.8 +ttl-more-than-600 700 A 5.6.7.8 +ttl-less-than-minimum 1100 A 5.6.7.8 +ttl-more-than-minimum 1300 A 5.6.7.8 diff --git a/bin/tests/system/dns64/tests.sh b/bin/tests/system/dns64/tests.sh index 9f0608b915..a7d234d4bb 100644 --- a/bin/tests/system/dns64/tests.sh +++ b/bin/tests/system/dns64/tests.sh @@ -14,7 +14,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.4 2011/01/07 23:47:07 tbox Exp $ +# $Id: tests.sh,v 1.4.14.1 2011/02/03 07:39:02 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -1271,5 +1271,69 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I: checking TTL less than 600 from zone ($n)" +#expect 500 +$DIG $DIGOPTS aaaa ttl-less-than-600.example +rec @10.53.0.1 > dig.out.ns1.test$n || ret=1 +grep -i "ttl-less-than-600.example..500.IN.AAAA" dig.out.ns1.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL more than 600 from zone ($n)" +#expect 700 +$DIG $DIGOPTS aaaa ttl-more-than-600.example +rec @10.53.0.1 > dig.out.ns1.test$n || ret=1 +grep -i "ttl-more-than-600.example..700.IN.AAAA" dig.out.ns1.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL less than minimum from zone ($n)" +#expect 1100 +$DIG $DIGOPTS aaaa ttl-less-than-minimum.example +rec @10.53.0.1 > dig.out.ns1.test$n || ret=1 +grep -i "ttl-less-than-minimum.example..1100.IN.AAAA" dig.out.ns1.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL limited to minimum from zone ($n)" +#expect 1200 +$DIG $DIGOPTS aaaa ttl-more-than-minimum.example +rec @10.53.0.1 > dig.out.ns1.test$n || ret=1 +grep -i "ttl-more-than-minimum.example..1200.IN.AAAA" dig.out.ns1.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL less than 600 via cache ($n)" +#expect 500 +$DIG $DIGOPTS aaaa ttl-less-than-600.example +rec -b 10.53.0.2 @10.53.0.2 > dig.out.ns1.test$n || ret=1 +grep -i "ttl-less-than-600.example..500.IN.AAAA" dig.out.ns1.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL more than 600 via cache ($n)" +#expect 700 +$DIG $DIGOPTS aaaa ttl-more-than-600.example +rec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep -i "ttl-more-than-600.example..700.IN.AAAA" dig.out.ns2.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL less than minimum via cache ($n)" +#expect 1100 +$DIG $DIGOPTS aaaa ttl-less-than-minimum.example +rec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep -i "ttl-less-than-minimum.example..1100.IN.AAAA" dig.out.ns2.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I: checking TTL limited to minimum via cache ($n)" +#expect 1200 +$DIG $DIGOPTS aaaa ttl-more-than-minimum.example +rec -b 10.53.0.2 @10.53.0.2 > dig.out.ns2.test$n || ret=1 +grep -i "ttl-more-than-minimum.example..1200.IN.AAAA" dig.out.ns2.test$n >/dev/null || ret=1 +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" exit $status diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index ab1efda811..c6c860daf7 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -18,7 +18,7 @@ - PERFORMANCE OF THIS SOFTWARE. --> - + BIND 9 Administrator Reference Manual @@ -5778,24 +5778,24 @@ options { not settable on a per-prefix basis. - Each dns64 supports a optional - clients acl which defines which clients - see this directive. If not defined it defaults to - any;. + Each dns64 supports an optional + clients ACL that determines which + clients are affected by this directive. If not defined, + it defaults to any;. - Each dns64 supports a optional - mapped acl which selects which - IPv4 addresses are to be mapped are in the corresponding + Each dns64 supports an optional + mapped ACL that selects which + IPv4 addresses are to be mapped in the corresponding A RRset. If not defined it defaults to any;. - Each dns64 supports a optional - exclude acl which selects which + Each dns64 supports an optional + exclude ACL that selects which IPv6 addresses will be ignored for the purposes - of determining if dns64 is to be applied. Any - non matching address will prevent any further + of determining whether dns64 is to be applied. + Any non-matching address will prevent further DNS64 processing from occurring for this client. diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c index eaa546db8b..447316200d 100644 --- a/lib/dns/ncache.c +++ b/lib/dns/ncache.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.c,v 1.50 2010/05/19 09:52:42 marka Exp $ */ +/* $Id: ncache.c,v 1.50.124.1 2011/02/03 07:39:03 marka Exp $ */ /*! \file */ @@ -35,7 +35,7 @@ #define DNS_NCACHE_RDATA 20U /* - * The format of an ncache rdata is a sequence of one or more records of + * The format of an ncache rdata is a sequence of zero or more records of * the following format: * * owner name @@ -223,42 +223,6 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, return (result); if (trust == 0xffff) { - /* - * We didn't find any authority data from which to create a - * negative cache rdataset. In particular, we have no SOA. - * - * We trust that the caller wants negative caching, so this - * means we have a "type 3 nxdomain" or "type 3 nodata" - * response (see RFC2308 for details). - * - * We will now build a suitable negative cache rdataset that - * will cause zero bytes to be emitted when converted to - * wire format. - */ - - /* - * The ownername must exist, but it doesn't matter what value - * it has. We use the root name. - */ - dns_name_toregion(dns_rootname, &r); - result = isc_buffer_copyregion(&buffer, &r); - if (result != ISC_R_SUCCESS) - return (result); - /* - * Copy the type and a zero rdata count to the buffer. - */ - isc_buffer_availableregion(&buffer, &r); - if (r.length < 5) - return (ISC_R_NOSPACE); - isc_buffer_putuint16(&buffer, 0); /* type */ - /* - * RFC2308, section 5, says that negative answers without - * SOAs should not be cached. - */ - ttl = 0; - /* - * Set trust. - */ if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 && message->counts[DNS_SECTION_ANSWER] == 0) { /* @@ -268,22 +232,7 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache, trust = dns_trust_authauthority; } else trust = dns_trust_additional; - isc_buffer_putuint8(&buffer, (unsigned char)trust); /* trust */ - isc_buffer_putuint16(&buffer, 0); /* count */ - - /* - * Now add it to the cache. - */ - if (next >= DNS_NCACHE_RDATA) - return (ISC_R_NOSPACE); - dns_rdata_init(&rdata[next]); - isc_buffer_remainingregion(&buffer, &r); - rdata[next].data = r.base; - rdata[next].length = r.length; - rdata[next].rdclass = ncrdatalist.rdclass; - rdata[next].type = 0; - rdata[next].flags = 0; - ISC_LIST_APPEND(ncrdatalist.rdata, &rdata[next], link); + ttl = 0; } INSIST(trust != 0xffff); diff --git a/lib/dns/rdataslab.c b/lib/dns/rdataslab.c index 1af469d681..bbb7e57218 100644 --- a/lib/dns/rdataslab.c +++ b/lib/dns/rdataslab.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.c,v 1.52 2010/02/25 05:08:01 tbox Exp $ */ +/* $Id: rdataslab.c,v 1.52.148.1 2011/02/03 07:39:03 marka Exp $ */ /*! \file */ @@ -144,21 +144,25 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, nalloc = dns_rdataset_count(rdataset); nitems = nalloc; - if (nitems == 0) + if (nitems == 0 && rdataset->type != 0) return (ISC_R_FAILURE); if (nalloc > 0xffff) return (ISC_R_NOSPACE); - x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata)); - if (x == NULL) - return (ISC_R_NOMEMORY); + + if (nalloc != 0) { + x = isc_mem_get(mctx, nalloc * sizeof(struct xrdata)); + if (x == NULL) + return (ISC_R_NOMEMORY); + } else + x = NULL; /* * Save all of the rdata members into an array. */ result = dns_rdataset_first(rdataset); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) goto free_rdatas; for (i = 0; i < nalloc && result == ISC_R_SUCCESS; i++) { INSIST(result == ISC_R_SUCCESS); @@ -223,11 +227,14 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, /* * Don't forget the last item! */ + if (nalloc != 0) { #if DNS_RDATASET_FIXED - buflen += (8 + x[i-1].rdata.length); + buflen += (8 + x[i-1].rdata.length); #else - buflen += (2 + x[i-1].rdata.length); + buflen += (2 + x[i-1].rdata.length); #endif + } + /* * Provide space to store the per RR meta data. */ @@ -316,7 +323,8 @@ dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx, result = ISC_R_SUCCESS; free_rdatas: - isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata)); + if (x != NULL) + isc_mem_put(mctx, x, nalloc * sizeof(struct xrdata)); return (result); }