]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3124. [bug] Use an rdataset attribute flag to indicate
authorEvan Hunt <each@isc.org>
Thu, 9 Jun 2011 00:42:48 +0000 (00:42 +0000)
committerEvan Hunt <each@isc.org>
Thu, 9 Jun 2011 00:42:48 +0000 (00:42 +0000)
negative-cache records rather than using rrtype 0;
this will prevent problems when that rrtype is
used in actual DNS packets. [RT #24777]

CHANGES
bin/tests/system/nsupdate/tests.sh
bin/tests/system/packet.pl [new file with mode: 0644]
lib/dns/include/dns/rdataset.h
lib/dns/masterdump.c
lib/dns/message.c
lib/dns/ncache.c
lib/dns/rbtdb.c
lib/dns/rdataset.c
lib/dns/resolver.c
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index c133c1ac2184104a7ea7ea12be4368ca40e2a7c7..3be17a535a46850e589ab0885ac2c4f18a50f340 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3124.  [bug]           Use an rdataset attribute flag to indicate
+                       negative-cache records rather than using rrtype 0;
+                       this will prevent problems when that rrtype is
+                       used in actual DNS packets. [RT #24777]
+
        --- 9.4-ESV-R5rc1 released ---
 
 3121.   [security]      An authoritative name server sending a negative
index 5ad42fbbbffe93965d444c1ab178967d82689537..3382665e7fee30cb3f2091dffd5fc8fb7822723d 100644 (file)
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.23 2004/03/05 05:01:55 marka Exp $
+# $Id: tests.sh,v 1.23.18.1 2011/06/09 00:42:47 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
 status=0
+n=0
 
 echo "I:fetching first copy of zone before update"
 $DIG +tcp +noadd +nosea +nostat +noquest +nocomm +nocmd example.nil.\
@@ -58,6 +59,60 @@ echo "I:comparing post-update copies to known good data"
 $PERL ../digcomp.pl knowngood.ns1.after dig.out.ns1 || status=1
 $PERL ../digcomp.pl knowngood.ns1.after dig.out.ns2 || status=1
 
+n=`expr $n + 1`
+ret=0
+echo "I:check TYPE=0 update is rejected by nsupdate ($n)"
+$NSUPDATE <<END > nsupdate.out 2>&1 && ret=1
+    server 10.53.0.1 5300
+    update add example.nil. 300 in type0 ""
+    send
+END
+grep "unknown class/type" nsupdate.out > /dev/null 2>&1 || ret=1
+if [ $ret -ne 0 ]; then
+    echo "I:failed"
+    status=1
+fi
+
+n=`expr $n + 1`
+ret=0
+echo "I:check TYPE=0 prerequisite is handled ($n)"
+$NSUPDATE <<END > nsupdate.out 2>&1 || ret=1
+    server 10.53.0.1 5300
+    prereq nxrrset example.nil. type0
+    send
+END
+$DIG +tcp version.bind txt ch @10.53.0.1 -p 5300 > dig.out.ns1.$n
+grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
+if [ $ret -ne 0 ]; then
+    echo "I:failed"
+    status=1
+fi
+
+n=`expr $n + 1`
+ret=0
+echo "I:check that TYPE=0 update is handled ($n)"
+echo "a0e4280000010000000100000000060001c00c000000fe000000000000" |
+$PERL ../packet.pl -a 10.53.0.1 -p 5300 -t tcp > /dev/null
+$DIG +tcp version.bind txt ch @10.53.0.1 -p 5300 > dig.out.ns1.$n
+grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
+if test $ret -ne 0
+then
+       echo "I:failed"
+        status=1
+fi
+
+n=`expr $n + 1`
+echo "I:check that TYPE=0 additional data is handled ($n)"
+echo "a0e4280000010000000000010000060001c00c000000fe000000000000" |
+$PERL ../packet.pl -a 10.53.0.1 -p 5300 -t tcp > /dev/null
+$DIG +tcp version.bind txt ch @10.53.0.1 -p 5300 > dig.out.ns1.$n
+grep "status: NOERROR" dig.out.ns1.$n > /dev/null || ret=1
+if test $ret -ne 0
+then
+       echo "I:failed"
+        status=1
+fi
+
 if $PERL -e 'use Net::DNS;' 2>/dev/null
 then
     echo "I:running update.pl test"
diff --git a/bin/tests/system/packet.pl b/bin/tests/system/packet.pl
new file mode 100644 (file)
index 0000000..7f63115
--- /dev/null
@@ -0,0 +1,107 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: packet.pl,v 1.2.36.2 2011/06/09 00:42:47 each Exp $
+
+# This is a tool for sending an arbitrary packet via UDP or TCP to an
+# arbitrary address and port.  The packet is specified in a file or on
+# the standard input, in the form of a series of bytes in hexidecimal.
+# Whitespace is ignored, as is anything following a '#' symbol.
+#
+# For example, the following input would generate normal query for 
+# isc.org/NS/IN":
+#
+#     # QID:
+#     0c d8
+#     # header:
+#     01 00 00 01 00 00 00 00 00 00
+#     # qname isc.org:
+#     03 69 73 63 03 6f 72 67 00
+#     # qtype NS:
+#     00 02
+#     # qclass IN:
+#     00 01
+#
+# Note that we do not wait for a response for the server.  This is simply
+# a way of injecting arbitrary packets to test server resposnes.
+#
+# Usage: packet.pl [-a <address>] [-p <port>] [-t (udp|tcp)] [filename]
+#
+# If not specified, address defaults to 127.0.0.1, port to 53, protocol
+# to udp, and file to stdin.
+#
+# XXX: Doesn't support IPv6 yet
+
+require 5.006.001;
+
+use strict;
+use Getopt::Std;
+use IO::File;
+use IO::Socket;
+
+sub usage {
+    print ("Usage: packet.pl [-a address] [-p port] [-t (tcp|udp)] [file]\n");
+    exit 1;
+}
+
+my %options={};
+getopts("a:p:t:", \%options);
+
+my $addr = "127.0.0.1";
+$addr = $options{a} if defined $options{a};
+
+my $port = 53;
+$port = $options{p} if defined $options{p};
+
+my $proto = "udp";
+$proto = lc $options{t} if defined $options{t};
+usage if ($proto !~ /^(udp|tcp)$/);
+
+my $file = "STDIN";
+if (@ARGV >= 1) {
+    my $filename = shift @ARGV;
+    open FH, "<$filename" or die "$filename: $!";
+    $file = "FH";
+}
+
+my $input = "";
+while (defined(my $line = <$file>) ) {
+    chomp $line;
+    $line =~ s/#.*$//;
+    $input .= $line;
+}
+
+$input =~ s/\s+//g;
+my $data = pack("H*", $input);
+my $len = length $data;
+
+my $output = unpack("H*", $data);
+print ("sending: $output\n");
+
+my $sock = IO::Socket::INET->new(PeerAddr => $addr, PeerPort => $port,
+                                Proto => $proto,) or die "$!";
+
+my $bytes;
+if ($proto eq "udp") {
+    $bytes = $sock->send($data);
+} else {
+    $bytes = $sock->syswrite(pack("n", $len), 2);
+    $bytes += $sock->syswrite($data, $len);
+}
+
+print ("sent $bytes bytes to $addr:$port\n");
+$sock->close;
+close $file;
index 08a083c6f08663db7f09534c9789e9c57ef5db37..bdc30c885ffa5cb707d2200bcd90740fc3adb64d 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rdataset.h,v 1.51.18.13 2011/05/27 23:49:08 tbox Exp $ */
+/* $Id: rdataset.h,v 1.51.18.14 2011/06/09 00:42:48 each Exp $ */
 
 #ifndef DNS_RDATASET_H
 #define DNS_RDATASET_H 1
@@ -187,6 +187,7 @@ struct dns_rdataset {
 #define DNS_RDATASETATTR_CHECKNAMES    0x00008000      /*%< Used by resolver. */
 #define DNS_RDATASETATTR_REQUIREDGLUE  0x00010000
 #define DNS_RDATASETATTR_LOADORDER     0x00020000
+#define DNS_RDATASETATTR_NEGATIVE      0x00200000
 
 /*%
  * _OMITDNSSEC:
index fb266dfe04de89048b5531bdd9243e01c4f7c60c..cbeea22267859fe88a22622d2089fda7af53e73b 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: masterdump.c,v 1.73.18.22 2011/05/27 23:49:06 tbox Exp $ */
+/* $Id: masterdump.c,v 1.73.18.23 2011/06/09 00:42:47 each Exp $ */
 
 /*! \file */
 
@@ -355,6 +355,7 @@ rdataset_totext(dns_rdataset_t *rdataset,
        isc_uint32_t current_ttl;
        isc_boolean_t current_ttl_valid;
        dns_rdatatype_t type;
+       unsigned int type_start;
 
        REQUIRE(DNS_RDATASET_VALID(rdataset));
 
@@ -436,29 +437,26 @@ rdataset_totext(dns_rdataset_t *rdataset,
                 * Type.
                 */
 
-               if (rdataset->type == 0) {
+               if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
                        type = rdataset->covers;
                } else {
                        type = rdataset->type;
                }
 
-               {
-                       unsigned int type_start;
-                       INDENT_TO(type_column);
-                       type_start = target->used;
-                       if (rdataset->type == 0)
-                               RETERR(str_totext("\\-", target));
-                       result = dns_rdatatype_totext(type, target);
-                       if (result != ISC_R_SUCCESS)
-                               return (result);
-                       column += (target->used - type_start);
-               }
+               INDENT_TO(type_column);
+               type_start = target->used;
+               if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+                       RETERR(str_totext("\\-", target));
+               result = dns_rdatatype_totext(type, target);
+               if (result != ISC_R_SUCCESS)
+                       return (result);
+               column += (target->used - type_start);
 
                /*
                 * Rdata.
                 */
                INDENT_TO(rdata_column);
-               if (rdataset->type == 0) {
+               if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
                        if (NXDOMAIN(rdataset))
                                RETERR(str_totext(";-$NXDOMAIN\n", target));
                        else
@@ -812,7 +810,7 @@ dump_rdatasets_text(isc_mem_t *mctx, dns_name_t *name,
                dns_rdataset_t *rds = sorted[i];
                if (ctx->style.flags & DNS_STYLEFLAG_TRUST)
                        fprintf(f, "; %s\n", dns_trust_totext(rds->trust));
-               if (rds->type == 0 &&
+               if (((rds->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
                    (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
                        /* Omit negative cache entries */
                } else {
@@ -968,7 +966,7 @@ dump_rdatasets_raw(isc_mem_t *mctx, dns_name_t *name,
                dns_rdataset_init(&rdataset);
                dns_rdatasetiter_current(rdsiter, &rdataset);
 
-               if (rdataset.type == 0 &&
+               if (((rdataset.attributes & DNS_RDATASETATTR_NEGATIVE) != 0) &&
                    (ctx->style.flags & DNS_STYLEFLAG_NCACHE) == 0) {
                        /* Omit negative cache entries */
                } else {
index 4073a0d283719a16a79aedd047b7aafcde30447c..d4f2057d8bee5274f9f7c60f0d9dc3335c49f326 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: message.c,v 1.222.18.18 2009/01/19 23:46:15 tbox Exp $ */
+/* $Id: message.c,v 1.222.18.19 2011/06/09 00:42:47 each Exp $ */
 
 /*! \file */
 
@@ -2437,7 +2437,7 @@ dns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
 
 isc_result_t
 dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
-       unsigned int first_section;
+       unsigned int clear_after;
        isc_result_t result;
 
        REQUIRE(DNS_MESSAGE_VALID(msg));
@@ -2451,11 +2451,11 @@ dns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
        if (want_question_section) {
                if (!msg->question_ok)
                        return (DNS_R_FORMERR);
-               first_section = DNS_SECTION_ANSWER;
+               clear_after = DNS_SECTION_ANSWER;
        } else
-               first_section = DNS_SECTION_QUESTION;
+               clear_after = DNS_SECTION_QUESTION;
        msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
-       msgresetnames(msg, first_section);
+       msgresetnames(msg, clear_after);
        msgresetopt(msg);
        msgresetsigs(msg, ISC_TRUE);
        msginitprivate(msg);
index d45c05a4a6aa769bbce2376debea4bdc3eea959d..761fb5f4cb2fd6f34be6b165297f45a211d2c93f 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: ncache.c,v 1.36.18.11 2011/05/31 02:18:34 marka Exp $ */
+/* $Id: ncache.c,v 1.36.18.12 2011/06/09 00:42:47 each Exp $ */
 
 /*! \file */
 
@@ -283,6 +283,7 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
        RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
                      == ISC_R_SUCCESS);
        ncrdataset.trust = trust;
+       ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
        if (message->rcode == dns_rcode_nxdomain)
                ncrdataset.attributes |= DNS_RDATASETATTR_NXDOMAIN;
 
@@ -311,6 +312,7 @@ dns_ncache_towire(dns_rdataset_t *rdataset, dns_compress_t *cctx,
 
        REQUIRE(rdataset != NULL);
        REQUIRE(rdataset->type == 0);
+       REQUIRE((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
 
        savedbuffer = *target;
        count = 0;
@@ -537,6 +539,7 @@ dns_ncache_getrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
 
        REQUIRE(ncacherdataset != NULL);
        REQUIRE(ncacherdataset->type == 0);
+       REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
        REQUIRE(name != NULL);
        REQUIRE(!dns_rdataset_isassociated(rdataset));
        REQUIRE(type != dns_rdatatype_rrsig);
@@ -613,6 +616,7 @@ dns_ncache_getsigrdataset(dns_rdataset_t *ncacherdataset, dns_name_t *name,
 
        REQUIRE(ncacherdataset != NULL);
        REQUIRE(ncacherdataset->type == 0);
+       REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
        REQUIRE(name != NULL);
        REQUIRE(!dns_rdataset_isassociated(rdataset));
 
@@ -712,6 +716,7 @@ dns_ncache_current(dns_rdataset_t *ncacherdataset, dns_name_t *found,
 
        REQUIRE(ncacherdataset != NULL);
        REQUIRE(ncacherdataset->type == 0);
+       REQUIRE((ncacherdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0);
        REQUIRE(found != NULL);
        REQUIRE(!dns_rdataset_isassociated(rdataset));
 
index b395335779ddfaca2b96c0b501ff0b4ad4d7a33a..a1ad2a4045a1dd747b5cfc43cf94e433a985f7cf 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rbtdb.c,v 1.196.18.66 2011/03/02 23:45:32 tbox Exp $ */
+/* $Id: rbtdb.c,v 1.196.18.67 2011/06/09 00:42:47 each Exp $ */
 
 /*! \file */
 
@@ -244,6 +244,7 @@ typedef struct rdatasetheader {
 #define RDATASET_ATTR_IGNORE           0x0004
 #define RDATASET_ATTR_RETAIN           0x0008
 #define RDATASET_ATTR_NXDOMAIN         0x0010
+#define RDATASET_ATTR_NEGATIVE          0x0100
 
 typedef struct acache_cbarg {
        dns_rdatasetadditional_t        type;
@@ -278,6 +279,8 @@ struct acachectl {
        (((header)->attributes & RDATASET_ATTR_RETAIN) != 0)
 #define NXDOMAIN(header) \
        (((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+#define NEGATIVE(header) \
+       (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
 
 #define DEFAULT_NODE_LOCK_COUNT                7       /*%< Should be prime. */
 #define DEFAULT_CACHE_NODE_LOCK_COUNT  1009    /*%< Should be prime. */
@@ -1878,6 +1881,8 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
        rdataset->covers = RBTDB_RDATATYPE_EXT(header->type);
        rdataset->ttl = header->ttl - now;
        rdataset->trust = header->trust;
+       if (NEGATIVE(header))
+               rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
        if (NXDOMAIN(header))
                rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
        rdataset->private1 = rbtdb;
@@ -3639,7 +3644,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
                *nodep = node;
        }
 
-       if (RBTDB_RDATATYPE_BASE(found->type) == 0) {
+       if (NEGATIVE(found)) {
                /*
                 * We found a negative cache entry.
                 */
@@ -4263,7 +4268,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
        if (found == NULL)
                return (ISC_R_NOTFOUND);
 
-       if (RBTDB_RDATATYPE_BASE(found->type) == 0) {
+       if (NEGATIVE(found)) {
                /*
                 * We found a negative cache entry.
                 */
@@ -4461,7 +4466,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
        negtype = 0;
        if (rbtversion == NULL && !newheader_nx) {
                rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
-               if (rdtype == 0) {
+               if (NEGATIVE(newheader)) {
                        /*
                         * We're adding a negative cache entry.
                         */
@@ -4889,6 +4894,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                now = 0;
        } else {
                newheader->serial = 1;
+               if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+                       newheader->attributes |= RDATASET_ATTR_NEGATIVE;
                if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
                        newheader->attributes |= RDATASET_ATTR_NXDOMAIN;
                if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
@@ -5984,7 +5991,7 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
 
        type = header->type;
        rdtype = RBTDB_RDATATYPE_BASE(header->type);
-       if (rdtype == 0) {
+       if (NEGATIVE(header)) {
                covers = RBTDB_RDATATYPE_EXT(header->type);
                negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
        } else
index 219e2b08108c8b3569f3ca6aaef16d089905cbcc..1b4c0df0965d5c44826421f2dbf0cd9b5336c0c4 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: rdataset.c,v 1.72.18.11 2011/05/27 23:49:07 tbox Exp $ */
+/* $Id: rdataset.c,v 1.72.18.12 2011/06/09 00:42:48 each Exp $ */
 
 /*! \file */
 
@@ -342,7 +342,7 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
                count = 1;
                result = dns_rdataset_first(rdataset);
                INSIST(result == ISC_R_NOMORE);
-       } else if (rdataset->type == 0) {
+       } else if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0) {
                /*
                 * This is a negative caching rdataset.
                 */
index 0de5373a75d1083ffbadcbe98a64e0504027f892..3af85fcdd1ece469f6263871701a37449a35e776 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.284.18.105 2011/01/27 23:45:12 tbox Exp $ */
+/* $Id: resolver.c,v 1.284.18.106 2011/06/09 00:42:48 each Exp $ */
 
 /*! \file */
 
@@ -401,6 +401,7 @@ struct dns_resolver {
                                         FCTX_ADDRINFO_FORWARDER) != 0)
 
 #define NXDOMAIN(r) (((r)->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
+#define NEGATIVE(r) (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
 
 #define dns_db_transfernode(a,b,c) do { (*c) = (*b); (*b) = NULL; } while (0)
 
@@ -986,7 +987,7 @@ fctx_sendevents(fetchctx_t *fctx, isc_result_t result, int line) {
                 * Negative results must be indicated in event->result.
                 */
                if (dns_rdataset_isassociated(event->rdataset) &&
-                   event->rdataset->type == dns_rdatatype_none) {
+                   NEGATIVE(event->rdataset)) {
                        INSIST(event->result == DNS_R_NCACHENXDOMAIN ||
                               event->result == DNS_R_NCACHENXRRSET);
                }
@@ -3951,7 +3952,7 @@ validated(isc_task_t *task, isc_event_t *event) {
        if (result != ISC_R_SUCCESS &&
            result != DNS_R_UNCHANGED)
                goto noanswer_response;
-       if (ardataset != NULL && ardataset->type == 0) {
+       if (ardataset != NULL && NEGATIVE(ardataset)) {
                if (NXDOMAIN(ardataset))
                        eresult = DNS_R_NCACHENXDOMAIN;
                else
@@ -4272,7 +4273,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
                                        result = ISC_R_SUCCESS;
                                        if (!need_validation &&
                                            ardataset != NULL &&
-                                           ardataset->type == 0) {
+                                           NEGATIVE(ardataset)) {
                                                /*
                                                 * The answer in the cache is
                                                 * better than the answer we
@@ -4402,7 +4403,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
                        if (result == DNS_R_UNCHANGED) {
                                if (ANSWER(rdataset) &&
                                    ardataset != NULL &&
-                                   ardataset->type == 0) {
+                                   NEGATIVE(ardataset)) {
                                        /*
                                         * The answer in the cache is better
                                         * than the answer we found, and is
@@ -4432,7 +4433,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
                         * Negative results must be indicated in event->result.
                         */
                        if (dns_rdataset_isassociated(event->rdataset) &&
-                           event->rdataset->type == dns_rdatatype_none) {
+                           NEGATIVE(event->rdataset)) {
                                INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
                                       eresult == DNS_R_NCACHENXRRSET);
                        }
@@ -4512,7 +4513,7 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
                 * care about whether it is DNS_R_NCACHENXDOMAIN or
                 * DNS_R_NCACHENXRRSET then extract it.
                 */
-               if (ardataset->type == 0) {
+               if (NEGATIVE(ardataset)) {
                        /*
                         * The cache data is a negative cache entry.
                         */
index 96a4cc7eadd171570c8c90a727aa4e98947758be..ef9f475cfdee69b9d8faced812dac75b3f93406a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.119.18.63 2011/05/27 01:46:22 marka Exp $ */
+/* $Id: validator.c,v 1.119.18.64 2011/06/09 00:42:48 each Exp $ */
 
 /*! \file */
 
 #define SHUTDOWN(v)            (((v)->attributes & VALATTR_SHUTDOWN) != 0)
 #define CANCELED(v)            (((v)->attributes & VALATTR_CANCELED) != 0)
 
+#define NEGATIVE(r)    (((r)->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+
 static void
 destroy(dns_validator_t *val);
 
@@ -649,7 +651,7 @@ dsvalidated(isc_task_t *task, isc_event_t *event) {
                name = dns_fixedname_name(&val->fname);
                if ((val->attributes & VALATTR_INSECURITY) != 0 &&
                    val->frdataset.covers == dns_rdatatype_ds &&
-                   val->frdataset.type == 0 &&
+                   NEGATIVE(&val->frdataset) &&
                    isdelegation(name, &val->frdataset, DNS_R_NCACHENXRRSET)) {
                        if (val->mustbesecure) {
                                validator_log(val, ISC_LOG_WARNING,
@@ -3387,7 +3389,7 @@ validator_start(isc_task_t *task, isc_event_t *event) {
                        val->attributes |= VALATTR_NEEDNODATA;
                result = nsecvalidate(val, ISC_FALSE);
        } else if (val->event->rdataset != NULL &&
-                   val->event->rdataset->type == 0)
+                   NEGATIVE(val->event->rdataset))
        {
                /*
                 * This is a nonexistence validation.