Browse Source

handle class ANY query correctly (ticket #80)

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1404 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya 15 years ago
parent
commit
461d4abe80

+ 2 - 9
src/lib/auth/data_source.cc

@@ -809,19 +809,12 @@ MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src)
 void
 void
 MetaDataSrc::findClosestEnclosure(NameMatch& match, const RRClass& qclass) const
 MetaDataSrc::findClosestEnclosure(NameMatch& match, const RRClass& qclass) const
 {
 {
-    if (qclass == RRClass::ANY()) {
-        isc_throw(Unexpected, "invalid query class");
-    }
-
-    if (getClass() != RRClass::ANY() && getClass() != qclass) {
+    if (getClass() != qclass &&
+        getClass() != RRClass::ANY() && qclass != RRClass::ANY()) {
         return;
         return;
     }
     }
 
 
     BOOST_FOREACH (ConstDataSrcPtr data_src, data_sources) {
     BOOST_FOREACH (ConstDataSrcPtr data_src, data_sources) {
-        if (data_src->getClass() != qclass) {
-            continue;
-        }
-
         data_src->findClosestEnclosure(match, qclass);
         data_src->findClosestEnclosure(match, qclass);
     }
     }
 }
 }

+ 5 - 5
src/lib/auth/sqlite3_datasrc.cc

@@ -342,7 +342,7 @@ void
 Sqlite3DataSrc::findClosestEnclosure(NameMatch& match,
 Sqlite3DataSrc::findClosestEnclosure(NameMatch& match,
                                      const RRClass& qclass) const
                                      const RRClass& qclass) const
 {
 {
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return;
         return;
     }
     }
 
 
@@ -482,7 +482,7 @@ Sqlite3DataSrc::findRRset(const Name& qname,
                           uint32_t& flags,
                           uint32_t& flags,
                           const Name* zonename) const
                           const Name* zonename) const
 {
 {
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return (ERROR);
         return (ERROR);
     }
     }
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
@@ -497,7 +497,7 @@ Sqlite3DataSrc::findExactRRset(const Name& qname,
                                uint32_t& flags,
                                uint32_t& flags,
                                const Name* zonename) const
                                const Name* zonename) const
 {
 {
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return (ERROR);
         return (ERROR);
     }
     }
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
@@ -521,7 +521,7 @@ Sqlite3DataSrc::findAddrs(const Name& qname,
                           uint32_t& flags,
                           uint32_t& flags,
                           const Name* zonename) const
                           const Name* zonename) const
 {
 {
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return (ERROR);
         return (ERROR);
     }
     }
     findRecords(qname, RRType::ANY(), target, zonename, ADDRESS, flags);
     findRecords(qname, RRType::ANY(), target, zonename, ADDRESS, flags);
@@ -535,7 +535,7 @@ Sqlite3DataSrc::findReferral(const Name& qname,
                              uint32_t& flags,
                              uint32_t& flags,
                              const Name* zonename) const
                              const Name* zonename) const
 {
 {
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
             return (ERROR);
             return (ERROR);
     }
     }
     findRecords(qname, RRType::ANY(), target, zonename, DELEGATION, flags);
     findRecords(qname, RRType::ANY(), target, zonename, DELEGATION, flags);

+ 2 - 2
src/lib/auth/static_datasrc.cc

@@ -108,7 +108,7 @@ StaticDataSrc::findClosestEnclosure(NameMatch& match,
     const Name& qname = match.qname();
     const Name& qname = match.qname();
     NameComparisonResult::NameRelation cmp;
     NameComparisonResult::NameRelation cmp;
 
 
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return;
         return;
     }
     }
 
 
@@ -134,7 +134,7 @@ StaticDataSrc::findRRset(const Name& qname,
                          const Name* zonename) const
                          const Name* zonename) const
 {
 {
     flags = 0;
     flags = 0;
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return (ERROR);
         return (ERROR);
     }
     }
 
 

+ 69 - 43
src/lib/auth/tests/datasrc_unittest.cc

@@ -51,15 +51,22 @@ namespace {
 const ElementPtr SQLITE_DBFILE_EXAMPLE = Element::createFromString(
 const ElementPtr SQLITE_DBFILE_EXAMPLE = Element::createFromString(
     "{ \"database_file\": \"testdata/example.org.sqlite3\"}");
     "{ \"database_file\": \"testdata/example.org.sqlite3\"}");
 
 
-TestDataSrc test_source;
-
 class DataSrcTest : public ::testing::Test {
 class DataSrcTest : public ::testing::Test {
 protected:
 protected:
     DataSrcTest() : obuffer(0), renderer(obuffer), msg(Message::PARSE) {
     DataSrcTest() : obuffer(0), renderer(obuffer), msg(Message::PARSE) {
-        sql3_source.init(SQLITE_DBFILE_EXAMPLE);
-        test_source.init();
+        DataSrcPtr sql3_source = DataSrcPtr(new Sqlite3DataSrc); 
+        sql3_source->init(SQLITE_DBFILE_EXAMPLE);
+        DataSrcPtr test_source = DataSrcPtr(new TestDataSrc);
+        test_source->init();
+        meta_source.addDataSrc(test_source);
+        meta_source.addDataSrc(sql3_source);
     }
     }
-    Sqlite3DataSrc sql3_source;
+    void QueryCommon(const RRClass& qclass);
+    void readAndProcessQuery(const char* datafile);
+    void createAndProcessQuery(const Name& qname, const RRClass& qclass,
+                               const RRType& qtype);
+
+    MetaDataSrc meta_source;
     OutputBuffer obuffer;
     OutputBuffer obuffer;
     MessageRenderer renderer;
     MessageRenderer renderer;
     Message msg;
     Message msg;
@@ -74,27 +81,26 @@ performQuery(DataSrc& data_source, Message& message) {
 }
 }
 
 
 void
 void
-readAndProcessQuery(Message& message, const char* datafile) {
+DataSrcTest::readAndProcessQuery(const char* datafile) {
     std::vector<unsigned char> data;
     std::vector<unsigned char> data;
     UnitTestUtil::readWireData(datafile, data);
     UnitTestUtil::readWireData(datafile, data);
 
 
     InputBuffer buffer(&data[0], data.size());
     InputBuffer buffer(&data[0], data.size());
-    message.fromWire(buffer);
+    msg.fromWire(buffer);
 
 
-    message.makeResponse();
-    performQuery(test_source, message);
+    msg.makeResponse();
+    performQuery(meta_source, msg);
 }
 }
 
 
 void
 void
-createAndProcessQuery(DataSrc& data_source, Message& message,
-                      const Name& qname, const RRClass& qclass,
-                      const RRType& qtype)
+DataSrcTest::createAndProcessQuery(const Name& qname, const RRClass& qclass,
+                                   const RRType& qtype)
 {
 {
-    message.makeResponse();
-    message.setOpcode(Opcode::QUERY());
-    message.addQuestion(Question(qname, qclass, qtype));
-    message.setHeaderFlag(MessageFlag::RD());
-    performQuery(data_source, message);
+    msg.makeResponse();
+    msg.setOpcode(Opcode::QUERY());
+    msg.addQuestion(Question(qname, qclass, qtype));
+    msg.setHeaderFlag(MessageFlag::RD());
+    performQuery(meta_source, msg);
 }
 }
 
 
 void
 void
@@ -112,8 +118,9 @@ headerCheck(const Message& message, const Rcode& rcode, const bool qrflag,
     EXPECT_EQ(arcount, message.getRRCount(Section::ADDITIONAL()));
     EXPECT_EQ(arcount, message.getRRCount(Section::ADDITIONAL()));
 }
 }
 
 
-TEST_F(DataSrcTest, Query) {
-    readAndProcessQuery(msg, "testdata/q_www");
+void
+DataSrcTest::QueryCommon(const RRClass& qclass) {
+    createAndProcessQuery(Name("www.example.com"), qclass, RRType::A());
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
 
@@ -160,8 +167,29 @@ TEST_F(DataSrcTest, Query) {
     EXPECT_TRUE(it->isLast());
     EXPECT_TRUE(it->isLast());
 }
 }
 
 
+TEST_F(DataSrcTest, Query) {
+    QueryCommon(RRClass::IN());
+}
+
+// Query class doesn't match any of the data source classes.  The result
+// should be the same as "NxZone".
+TEST_F(DataSrcTest, QueryClassMismatch) {
+    createAndProcessQuery(Name("www.example.com"), RRClass::CH(), RRType::A());
+    headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
+
+    EXPECT_EQ(Rcode::REFUSED(), msg.getRcode());
+    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::QR()));
+    EXPECT_FALSE(msg.getHeaderFlag(MessageFlag::AA()));
+    EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::RD()));
+}
+
+// Query class of any should match the first data source.
+TEST_F(DataSrcTest, QueryClassAny) {
+    QueryCommon(RRClass::ANY());
+}
+
 TEST_F(DataSrcTest, NSQuery) {
 TEST_F(DataSrcTest, NSQuery) {
-    readAndProcessQuery(msg, "testdata/q_example_ns");
+    readAndProcessQuery("testdata/q_example_ns");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 0, 6);
 
 
@@ -183,7 +211,7 @@ TEST_F(DataSrcTest, NSQuery) {
 }
 }
 
 
 TEST_F(DataSrcTest, NxRRset) {
 TEST_F(DataSrcTest, NxRRset) {
-    readAndProcessQuery(msg, "testdata/q_example_ptr");
+    readAndProcessQuery("testdata/q_example_ptr");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 4, 0);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 4, 0);
 
 
@@ -194,7 +222,7 @@ TEST_F(DataSrcTest, NxRRset) {
 }
 }
 
 
 TEST_F(DataSrcTest, Nxdomain) {
 TEST_F(DataSrcTest, Nxdomain) {
-    readAndProcessQuery(msg, "testdata/q_glork");
+    readAndProcessQuery("testdata/q_glork");
 
 
     headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 6, 0);
     headerCheck(msg, Rcode::NXDOMAIN(), true, true, true, 0, 6, 0);
 
 
@@ -207,7 +235,7 @@ TEST_F(DataSrcTest, Nxdomain) {
 }
 }
 
 
 TEST_F(DataSrcTest, NxZone) {
 TEST_F(DataSrcTest, NxZone) {
-    readAndProcessQuery(msg, "testdata/q_spork");
+    readAndProcessQuery("testdata/q_spork");
 
 
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
     headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
 
 
@@ -215,11 +243,10 @@ TEST_F(DataSrcTest, NxZone) {
     EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::QR()));
     EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::QR()));
     EXPECT_FALSE(msg.getHeaderFlag(MessageFlag::AA()));
     EXPECT_FALSE(msg.getHeaderFlag(MessageFlag::AA()));
     EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::RD()));
     EXPECT_TRUE(msg.getHeaderFlag(MessageFlag::RD()));
-
 }
 }
 
 
 TEST_F(DataSrcTest, Wildcard) {
 TEST_F(DataSrcTest, Wildcard) {
-    readAndProcessQuery(msg, "testdata/q_wild_a");
+    readAndProcessQuery("testdata/q_wild_a");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
 
@@ -268,14 +295,14 @@ TEST_F(DataSrcTest, WildcardNodata) {
 
 
     // Check that a query for a data type not covered by the wildcard
     // Check that a query for a data type not covered by the wildcard
     // returns NOERROR
     // returns NOERROR
-    readAndProcessQuery(msg, "testdata/q_wild_aaaa");
+    readAndProcessQuery("testdata/q_wild_aaaa");
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 2, 0);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 2, 0);
 }
 }
 
 
 TEST_F(DataSrcTest, WildcardCname) {
 TEST_F(DataSrcTest, WildcardCname) {
     // Check that wildcard answers containing CNAMES are followed
     // Check that wildcard answers containing CNAMES are followed
     // correctly
     // correctly
-    readAndProcessQuery(msg, "testdata/q_wild2_a");
+    readAndProcessQuery("testdata/q_wild2_a");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
 
@@ -334,7 +361,7 @@ TEST_F(DataSrcTest, WildcardCname) {
 }
 }
 
 
 TEST_F(DataSrcTest, AuthDelegation) {
 TEST_F(DataSrcTest, AuthDelegation) {
-    readAndProcessQuery(msg, "testdata/q_sql1");
+    readAndProcessQuery("testdata/q_sql1");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
 
@@ -380,7 +407,7 @@ TEST_F(DataSrcTest, AuthDelegation) {
 }
 }
 
 
 TEST_F(DataSrcTest, Dname) {
 TEST_F(DataSrcTest, Dname) {
-    readAndProcessQuery(msg, "testdata/q_dname");
+    readAndProcessQuery("testdata/q_dname");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 5, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 5, 4, 6);
 
 
@@ -428,7 +455,7 @@ TEST_F(DataSrcTest, Dname) {
 }
 }
 
 
 TEST_F(DataSrcTest, Cname) {
 TEST_F(DataSrcTest, Cname) {
-    readAndProcessQuery(msg, "testdata/q_cname");
+    readAndProcessQuery("testdata/q_cname");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 0, 0);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 0, 0);
 
 
@@ -446,7 +473,7 @@ TEST_F(DataSrcTest, Cname) {
 }
 }
 
 
 TEST_F(DataSrcTest, CnameInt) {
 TEST_F(DataSrcTest, CnameInt) {
-    readAndProcessQuery(msg, "testdata/q_cname_int");
+    readAndProcessQuery("testdata/q_cname_int");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
 
@@ -472,7 +499,7 @@ TEST_F(DataSrcTest, CnameInt) {
 }
 }
 
 
 TEST_F(DataSrcTest, CnameExt) {
 TEST_F(DataSrcTest, CnameExt) {
-    readAndProcessQuery(msg, "testdata/q_cname_ext");
+    readAndProcessQuery("testdata/q_cname_ext");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 4, 4, 6);
 
 
@@ -496,7 +523,7 @@ TEST_F(DataSrcTest, CnameExt) {
 }
 }
 
 
 TEST_F(DataSrcTest, Delegation) {
 TEST_F(DataSrcTest, Delegation) {
-    readAndProcessQuery(msg, "testdata/q_subzone");
+    readAndProcessQuery("testdata/q_subzone");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
 
@@ -526,7 +553,7 @@ TEST_F(DataSrcTest, Delegation) {
 }
 }
 
 
 TEST_F(DataSrcTest, NSDelegation) {
 TEST_F(DataSrcTest, NSDelegation) {
-    readAndProcessQuery(msg, "testdata/q_subzone_ns");
+    readAndProcessQuery("testdata/q_subzone_ns");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
 
@@ -558,7 +585,7 @@ TEST_F(DataSrcTest, NSDelegation) {
 TEST_F(DataSrcTest, ANYZonecut) {
 TEST_F(DataSrcTest, ANYZonecut) {
     // An ANY query at a zone cut should behave the same as any other
     // An ANY query at a zone cut should behave the same as any other
     // delegation
     // delegation
-    readAndProcessQuery(msg, "testdata/q_subzone_any");
+    readAndProcessQuery("testdata/q_subzone_any");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 5, 2);
 
 
@@ -588,7 +615,7 @@ TEST_F(DataSrcTest, ANYZonecut) {
 }
 }
 
 
 TEST_F(DataSrcTest, NSECZonecut) {
 TEST_F(DataSrcTest, NSECZonecut) {
-    readAndProcessQuery(msg, "testdata/q_subzone_nsec");
+    readAndProcessQuery("testdata/q_subzone_nsec");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 2, 4, 6);
 
 
@@ -616,7 +643,7 @@ TEST_F(DataSrcTest, NSECZonecut) {
 }
 }
 
 
 TEST_F(DataSrcTest, DS) {
 TEST_F(DataSrcTest, DS) {
-    readAndProcessQuery(msg, "testdata/q_subzone_ds");
+    readAndProcessQuery("testdata/q_subzone_ds");
 
 
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 3, 4, 6);
     headerCheck(msg, Rcode::NOERROR(), true, true, true, 3, 4, 6);
 
 
@@ -644,16 +671,16 @@ TEST_F(DataSrcTest, DS) {
 }
 }
 
 
 TEST_F(DataSrcTest, CNAMELoop) {
 TEST_F(DataSrcTest, CNAMELoop) {
-    createAndProcessQuery(test_source, msg, Name("loop1.example.com"),
-                          RRClass::IN(), RRType::A());
+    createAndProcessQuery(Name("loop1.example.com"), RRClass::IN(),
+                          RRType::A());
 }
 }
 
 
 // NSEC query for the name of a zone cut for non-secure delegation.
 // NSEC query for the name of a zone cut for non-secure delegation.
 // Should return normal referral.
 // Should return normal referral.
 #if 0                           // currently fails
 #if 0                           // currently fails
 TEST_F(DataSrcTest, NSECZonecutOfNonsecureZone) {
 TEST_F(DataSrcTest, NSECZonecutOfNonsecureZone) {
-    createAndProcessQuery(sql3_source, msg, Name("sub.example.org"),
-                          RRClass::IN(), RRType::NSEC());
+    createAndProcessQuery(Name("sub.example.org"), RRClass::IN(),
+                          RRType::NSEC());
 
 
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 1, 1);
     headerCheck(msg, Rcode::NOERROR(), true, false, true, 0, 1, 1);
 
 
@@ -688,8 +715,7 @@ TEST_F(DataSrcTest, NSECZonecutOfNonsecureZone) {
 
 
 #if 0                           // currently fails
 #if 0                           // currently fails
 TEST_F(DataSrcTest, RootDSQuery) {
 TEST_F(DataSrcTest, RootDSQuery) {
-    createAndProcessQuery(test_source, msg, Name("."),
-                          RRClass::IN(), RRType::DS());
+    createAndProcessQuery(Name("."), RRClass::IN(), RRType::DS());
 }
 }
 #endif
 #endif
 
 

+ 115 - 66
src/lib/auth/tests/sqlite3_unittest.cc

@@ -100,6 +100,7 @@ typedef enum {
 class Sqlite3DataSourceTest : public ::testing::Test {
 class Sqlite3DataSourceTest : public ::testing::Test {
 protected:
 protected:
     Sqlite3DataSourceTest() : rrclass(RRClass::IN()),
     Sqlite3DataSourceTest() : rrclass(RRClass::IN()),
+                              rrclass_notmatch(RRClass::CH()),
                               rrtype(RRType::A()), rrttl(RRTTL(3600)),
                               rrtype(RRType::A()), rrttl(RRTTL(3600)),
                               find_flags(0), rrset_matched(0), rrset_count(0)
                               find_flags(0), rrset_matched(0), rrset_count(0)
     {
     {
@@ -175,6 +176,7 @@ protected:
     Sqlite3DataSrc data_source;
     Sqlite3DataSrc data_source;
     // we allow these to be modified in the test
     // we allow these to be modified in the test
     RRClass rrclass;
     RRClass rrclass;
+    RRClass rrclass_notmatch;
     RRType rrtype;
     RRType rrtype;
     RRTTL rrttl;
     RRTTL rrttl;
     RRsetList result_sets;
     RRsetList result_sets;
@@ -225,6 +227,9 @@ protected:
     vector<string> child_sig_data;
     vector<string> child_sig_data;
     vector<string> nsec3_data;
     vector<string> nsec3_data;
     vector<string> nsec3_sig_data;
     vector<string> nsec3_sig_data;
+
+    void findReferralRRsetCommon(const Name& qname, const RRClass& qclass);
+    void findAddressRRsetCommon(const RRClass& qclass);
 };
 };
 
 
 void
 void
@@ -279,9 +284,9 @@ checkRRset(RRsetPtr rrset, const Name& expected_name,
 void
 void
 checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
 checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
           const Name& expected_name, const Name* zone_name,
           const Name& expected_name, const Name* zone_name,
-          const RRClass& expected_class, const RRType& expected_type,
-          const vector<RRTTL>& expected_ttls, const uint32_t expected_flags,
-          const vector<RRType>& expected_types,
+          const RRClass& qclass, const RRClass& expected_class,
+          const RRType& expected_type, const vector<RRTTL>& expected_ttls,
+          const uint32_t expected_flags, const vector<RRType>& expected_types,
           const vector<const vector<string>* >& expected_answers,
           const vector<const vector<string>* >& expected_answers,
           const vector<const vector<string>* >& expected_signatures)
           const vector<const vector<string>* >& expected_signatures)
 {
 {
@@ -293,26 +298,25 @@ checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
     switch (mode) {
     switch (mode) {
     case NORMAL:
     case NORMAL:
         EXPECT_EQ(DataSrc::SUCCESS,
         EXPECT_EQ(DataSrc::SUCCESS,
-                  data_source.findRRset(expected_name, expected_class,
+                  data_source.findRRset(expected_name, qclass,
                                         expected_type, result_sets, find_flags,
                                         expected_type, result_sets, find_flags,
                                         zone_name));
                                         zone_name));
         break;
         break;
     case EXACT:
     case EXACT:
         EXPECT_EQ(DataSrc::SUCCESS,
         EXPECT_EQ(DataSrc::SUCCESS,
-                  data_source.findExactRRset(expected_name,
-                                             expected_class, expected_type,
-                                             result_sets, find_flags,
-                                             zone_name));
+                  data_source.findExactRRset(expected_name, qclass,
+                                             expected_type, result_sets,
+                                             find_flags, zone_name));
         break;
         break;
     case ADDRESS:
     case ADDRESS:
         EXPECT_EQ(DataSrc::SUCCESS,
         EXPECT_EQ(DataSrc::SUCCESS,
-                  data_source.findAddrs(expected_name, expected_class,
-                                        result_sets, find_flags, zone_name));
+                  data_source.findAddrs(expected_name, qclass, result_sets,
+                                        find_flags, zone_name));
         break;
         break;
     case REFERRAL:
     case REFERRAL:
         EXPECT_EQ(DataSrc::SUCCESS,
         EXPECT_EQ(DataSrc::SUCCESS,
-                  data_source.findReferral(expected_name, expected_class,
-                                           result_sets, find_flags, zone_name));
+                  data_source.findReferral(expected_name, qclass, result_sets,
+                                           find_flags, zone_name));
         break;
         break;
     }
     }
     EXPECT_EQ(expected_flags, find_flags);
     EXPECT_EQ(expected_flags, find_flags);
@@ -339,8 +343,9 @@ checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
 void
 void
 checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
 checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
           const Name& expected_name, const Name* zone_name,
           const Name& expected_name, const Name* zone_name,
-          const RRClass& expected_class, const RRType& expected_type,
-          const RRTTL& expected_rrttl, const uint32_t expected_flags,
+          const RRClass& qclass, const RRClass& expected_class,
+          const RRType& expected_type, const RRTTL& expected_rrttl,
+          const uint32_t expected_flags,
           const vector<string>& expected_data,
           const vector<string>& expected_data,
           const vector<string>* expected_sig_data)
           const vector<string>* expected_sig_data)
 {
 {
@@ -354,7 +359,7 @@ checkFind(FindMode mode, const Sqlite3DataSrc& data_source,
     answers.push_back(&expected_data);
     answers.push_back(&expected_data);
     signatures.push_back(expected_sig_data);
     signatures.push_back(expected_sig_data);
 
 
-    checkFind(mode, data_source, expected_name, zone_name,
+    checkFind(mode, data_source, expected_name, zone_name, qclass,
               expected_class, expected_type, ttls, expected_flags, types,
               expected_class, expected_type, ttls, expected_flags, types,
               answers, signatures);
               answers, signatures);
 }
 }
@@ -442,17 +447,26 @@ TEST_F(Sqlite3DataSourceTest, findClosestEnclosureNoMatch) {
 
 
 TEST_F(Sqlite3DataSourceTest, findClosestClassMismatch) {
 TEST_F(Sqlite3DataSourceTest, findClosestClassMismatch) {
     NameMatch name_match(www_name);
     NameMatch name_match(www_name);
-    data_source.findClosestEnclosure(name_match, RRClass::CH());
+    data_source.findClosestEnclosure(name_match, rrclass_notmatch);
     EXPECT_EQ(NULL, name_match.closestName());
     EXPECT_EQ(NULL, name_match.closestName());
     EXPECT_EQ(NULL, name_match.bestDataSrc());
     EXPECT_EQ(NULL, name_match.bestDataSrc());
 }
 }
 
 
+// If the query class is ANY, the result should be the same as the case where
+// the class exactly matches.
+TEST_F(Sqlite3DataSourceTest, findClosestClassAny) {
+    NameMatch name_match(www_name);
+    data_source.findClosestEnclosure(name_match, RRClass::ANY());
+    EXPECT_EQ(zone_name, *name_match.closestName());
+    EXPECT_EQ(&data_source, name_match.bestDataSrc());
+}
+
 TEST_F(Sqlite3DataSourceTest, findRRsetNormal) {
 TEST_F(Sqlite3DataSourceTest, findRRsetNormal) {
     // Without specifying the zone name, and then with the zone name
     // Without specifying the zone name, and then with the zone name
-    checkFind(NORMAL, data_source, www_name, NULL, rrclass, rrtype,
+    checkFind(NORMAL, data_source, www_name, NULL, rrclass, rrclass, rrtype,
               rrttl, 0, common_a_data, &common_sig_data);
               rrttl, 0, common_a_data, &common_sig_data);
 
 
-    checkFind(NORMAL, data_source, www_name, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, www_name, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
 
 
     // With a zone name that doesn't match
     // With a zone name that doesn't match
@@ -465,10 +479,20 @@ TEST_F(Sqlite3DataSourceTest, findRRsetNormal) {
 
 
 TEST_F(Sqlite3DataSourceTest, findRRsetClassMismatch) {
 TEST_F(Sqlite3DataSourceTest, findRRsetClassMismatch) {
     EXPECT_EQ(DataSrc::ERROR,
     EXPECT_EQ(DataSrc::ERROR,
-              data_source.findRRset(www_name, RRClass::CH(), rrtype,
+              data_source.findRRset(www_name, rrclass_notmatch, rrtype,
                                     result_sets, find_flags, NULL));
                                     result_sets, find_flags, NULL));
 }
 }
 
 
+TEST_F(Sqlite3DataSourceTest, findRRsetClassAny) {
+    checkFind(NORMAL, data_source, www_name, NULL, RRClass::ANY(), rrclass,
+              rrtype, rrttl, 0, common_a_data, &common_sig_data);
+}
+
+TEST_F(Sqlite3DataSourceTest, findRRsetClassClassAny) {
+    checkFind(NORMAL, data_source, www_name, NULL, RRClass::ANY(), rrclass,
+              rrtype, rrttl, 0, common_a_data, &common_sig_data);
+}
+
 TEST_F(Sqlite3DataSourceTest, findRRsetNormalANY) {
 TEST_F(Sqlite3DataSourceTest, findRRsetNormalANY) {
     types.push_back(RRType::A());
     types.push_back(RRType::A());
     types.push_back(RRType::NSEC());
     types.push_back(RRType::NSEC());
@@ -480,19 +504,19 @@ TEST_F(Sqlite3DataSourceTest, findRRsetNormalANY) {
     signatures.push_back(&www_nsec_sig_data);
     signatures.push_back(&www_nsec_sig_data);
 
 
     rrtype = RRType::ANY();
     rrtype = RRType::ANY();
-    checkFind(NORMAL, data_source, www_name, NULL, rrclass, rrtype,
+    checkFind(NORMAL, data_source, www_name, NULL, rrclass, rrclass, rrtype,
               ttls, 0, types, answers, signatures);
               ttls, 0, types, answers, signatures);
 
 
-    checkFind(NORMAL, data_source, www_name, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, www_name, &zone_name, rrclass, rrclass,
               rrtype, ttls, 0, types, answers, signatures);
               rrtype, ttls, 0, types, answers, signatures);
 }
 }
 
 
 // Case insensitive lookup
 // Case insensitive lookup
 TEST_F(Sqlite3DataSourceTest, findRRsetNormalCase) {
 TEST_F(Sqlite3DataSourceTest, findRRsetNormalCase) {
-    checkFind(NORMAL, data_source, www_upper_name, NULL, rrclass,
+    checkFind(NORMAL, data_source, www_upper_name, NULL, rrclass, rrclass,
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
 
 
-    checkFind(NORMAL, data_source, www_upper_name, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, www_upper_name, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
 
 
     EXPECT_EQ(DataSrc::SUCCESS,
     EXPECT_EQ(DataSrc::SUCCESS,
@@ -504,10 +528,10 @@ TEST_F(Sqlite3DataSourceTest, findRRsetNormalCase) {
 
 
 TEST_F(Sqlite3DataSourceTest, findRRsetApexNS) {
 TEST_F(Sqlite3DataSourceTest, findRRsetApexNS) {
     rrtype = RRType::NS();
     rrtype = RRType::NS();
-    checkFind(NORMAL, data_source, zone_name, NULL, rrclass, rrtype,
+    checkFind(NORMAL, data_source, zone_name, NULL, rrclass, rrclass, rrtype,
               rrttl, DataSrc::REFERRAL, apex_ns_data, &apex_ns_sig_data);
               rrttl, DataSrc::REFERRAL, apex_ns_data, &apex_ns_sig_data);
 
 
-    checkFind(NORMAL, data_source, zone_name, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, zone_name, &zone_name, rrclass, rrclass,
               rrtype, rrttl, DataSrc::REFERRAL, apex_ns_data,
               rrtype, rrttl, DataSrc::REFERRAL, apex_ns_data,
               &apex_ns_sig_data);
               &apex_ns_sig_data);
 
 
@@ -544,10 +568,10 @@ TEST_F(Sqlite3DataSourceTest, findRRsetApexANY) {
 
 
     // there is an NS at the zone apex, so the REFERRAL flag should
     // there is an NS at the zone apex, so the REFERRAL flag should
     // be set, but will ordinarily be ignored by the caller
     // be set, but will ordinarily be ignored by the caller
-    checkFind(NORMAL, data_source, zone_name, NULL, rrclass, rrtype,
+    checkFind(NORMAL, data_source, zone_name, NULL, rrclass, rrclass, rrtype,
               ttls, DataSrc::REFERRAL, types, answers, signatures);
               ttls, DataSrc::REFERRAL, types, answers, signatures);
 
 
-    checkFind(NORMAL, data_source, zone_name, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, zone_name, &zone_name, rrclass, rrclass,
               rrtype, ttls, DataSrc::REFERRAL, types, answers, signatures);
               rrtype, ttls, DataSrc::REFERRAL, types, answers, signatures);
 }
 }
 
 
@@ -565,7 +589,7 @@ TEST_F(Sqlite3DataSourceTest, findRRsetMixedANY) {
     signatures.push_back(NULL);
     signatures.push_back(NULL);
 
 
     rrtype = RRType::ANY();
     rrtype = RRType::ANY();
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, ttls, 0, types, answers, signatures);
               rrtype, ttls, 0, types, answers, signatures);
 }
 }
 
 
@@ -593,9 +617,9 @@ TEST_F(Sqlite3DataSourceTest, findRRsetApexNXRRSET) {
 // point of view, but perform minimal tests anyway.
 // point of view, but perform minimal tests anyway.
 TEST_F(Sqlite3DataSourceTest, findRRsetWildcard) {
 TEST_F(Sqlite3DataSourceTest, findRRsetWildcard) {
     const Name qname("*.wild.example.com");
     const Name qname("*.wild.example.com");
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, rrttl, 0, wild_a_data, &common_sig_data);
               rrtype, rrttl, 0, wild_a_data, &common_sig_data);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, wild_a_data, &common_sig_data);
               rrtype, rrttl, 0, wild_a_data, &common_sig_data);
 }
 }
 
 
@@ -622,9 +646,9 @@ TEST_F(Sqlite3DataSourceTest, findRRsetDNAME) {
     const Name qname("dname.example.com");
     const Name qname("dname.example.com");
 
 
     rrtype = RRType::DNAME();
     rrtype = RRType::DNAME();
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, rrttl, 0, dname_data, &dname_sig_data);
               rrtype, rrttl, 0, dname_data, &dname_sig_data);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, dname_data, &dname_sig_data);
               rrtype, rrttl, 0, dname_data, &dname_sig_data);
 }
 }
 
 
@@ -634,9 +658,9 @@ TEST_F(Sqlite3DataSourceTest, findRRsetCNAME) {
     // This qname only has the CNAME (+ sigs).  CNAME query is not different
     // This qname only has the CNAME (+ sigs).  CNAME query is not different
     // from ordinary queries.
     // from ordinary queries.
     rrtype = RRType::CNAME();
     rrtype = RRType::CNAME();
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
 
 
     // queries for (ordinary) different RR types that match the CNAME.
     // queries for (ordinary) different RR types that match the CNAME.
@@ -646,18 +670,18 @@ TEST_F(Sqlite3DataSourceTest, findRRsetCNAME) {
     ttls.push_back(rrttl);
     ttls.push_back(rrttl);
     answers.push_back(&cname_data);
     answers.push_back(&cname_data);
     signatures.push_back(&cname_sig_data);
     signatures.push_back(&cname_sig_data);
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, ttls, DataSrc::CNAME_FOUND, types, answers, signatures);
               rrtype, ttls, DataSrc::CNAME_FOUND, types, answers, signatures);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, ttls, DataSrc::CNAME_FOUND, types, answers, signatures);
               rrtype, ttls, DataSrc::CNAME_FOUND, types, answers, signatures);
 
 
     // NSEC query that match the CNAME.
     // NSEC query that match the CNAME.
     // CNAME_FOUND flag is NOT set, and the NSEC RR is returned instead of
     // CNAME_FOUND flag is NOT set, and the NSEC RR is returned instead of
     // CNAME.
     // CNAME.
     rrtype = RRType::NSEC();
     rrtype = RRType::NSEC();
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, RRTTL(7200), 0, cname_nsec_data, &cname_nsec_sig_data);
               rrtype, RRTTL(7200), 0, cname_nsec_data, &cname_nsec_sig_data);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, RRTTL(7200), 0, cname_nsec_data, &cname_nsec_sig_data);
               rrtype, RRTTL(7200), 0, cname_nsec_data, &cname_nsec_sig_data);
 }
 }
 
 
@@ -696,9 +720,9 @@ TEST_F(Sqlite3DataSourceTest, findRRsetDelegationAtZoneCut) {
     // For NS query, RRset is returned with the REFERRAL flag.  No RRSIG should
     // For NS query, RRset is returned with the REFERRAL flag.  No RRSIG should
     // be provided.
     // be provided.
     rrtype = RRType::NS();
     rrtype = RRType::NS();
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, rrttl, DataSrc::REFERRAL, delegation_ns_data, NULL);
               rrtype, rrttl, DataSrc::REFERRAL, delegation_ns_data, NULL);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, rrttl, DataSrc::REFERRAL, delegation_ns_data, NULL);
               rrtype, rrttl, DataSrc::REFERRAL, delegation_ns_data, NULL);
 
 
     // For ANY query.  At the backend data source level, it returns all
     // For ANY query.  At the backend data source level, it returns all
@@ -717,20 +741,20 @@ TEST_F(Sqlite3DataSourceTest, findRRsetDelegationAtZoneCut) {
     signatures.push_back(&delegation_nsec_sig_data);
     signatures.push_back(&delegation_nsec_sig_data);
     signatures.push_back(&delegation_ds_sig_data);
     signatures.push_back(&delegation_ds_sig_data);
 
 
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, ttls, DataSrc::REFERRAL, types, answers,
               rrtype, ttls, DataSrc::REFERRAL, types, answers,
               signatures);
               signatures);
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, ttls, DataSrc::REFERRAL, types, answers,
               rrtype, ttls, DataSrc::REFERRAL, types, answers,
               signatures);
               signatures);
 
 
     // For NSEC query.  At the backend data source level, it returns NSEC+
     // For NSEC query.  At the backend data source level, it returns NSEC+
     // RRSIG with the referral flag.
     // RRSIG with the referral flag.
     rrtype = RRType::NSEC();
     rrtype = RRType::NSEC();
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, RRTTL(7200), DataSrc::REFERRAL, delegation_nsec_data,
               rrtype, RRTTL(7200), DataSrc::REFERRAL, delegation_nsec_data,
               &delegation_nsec_sig_data);
               &delegation_nsec_sig_data);
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, RRTTL(7200), DataSrc::REFERRAL, delegation_nsec_data,
               rrtype, RRTTL(7200), DataSrc::REFERRAL, delegation_nsec_data,
               &delegation_nsec_sig_data);
               &delegation_nsec_sig_data);
 }
 }
@@ -741,7 +765,7 @@ TEST_F(Sqlite3DataSourceTest, findRRsetInChildZone) {
 
 
     // If we don't specify the zone, the data source should identify the
     // If we don't specify the zone, the data source should identify the
     // best matching zone.
     // best matching zone.
-    checkFind(NORMAL, data_source, qname, NULL, rrclass,
+    checkFind(NORMAL, data_source, qname, NULL, rrclass, rrclass,
               rrtype, rrttl, 0, child_a_data, &child_sig_data);
               rrtype, rrttl, 0, child_a_data, &child_sig_data);
 
 
     // If we specify the parent zone, it's treated as NXDOMAIN because it's
     // If we specify the parent zone, it's treated as NXDOMAIN because it's
@@ -753,23 +777,27 @@ TEST_F(Sqlite3DataSourceTest, findRRsetInChildZone) {
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
 
 
     // If we specify the child zone, it should be the same as the first case.
     // If we specify the child zone, it should be the same as the first case.
-    checkFind(NORMAL, data_source, qname, &child_zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &child_zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, child_a_data, &child_sig_data);
               rrtype, rrttl, 0, child_a_data, &child_sig_data);
 }
 }
 
 
 TEST_F(Sqlite3DataSourceTest, findExactRRset) {
 TEST_F(Sqlite3DataSourceTest, findExactRRset) {
     // Normal case.  No different than findRRset.
     // Normal case.  No different than findRRset.
-    checkFind(EXACT, data_source, www_name, &zone_name, rrclass, rrtype,
-              rrttl, 0, common_a_data, &common_sig_data);
+    checkFind(EXACT, data_source, www_name, &zone_name, rrclass, rrclass,
+              rrtype, rrttl, 0, common_a_data, &common_sig_data);
 }
 }
 
 
 TEST_F(Sqlite3DataSourceTest, findExactRRsetClassMismatch) {
 TEST_F(Sqlite3DataSourceTest, findExactRRsetClassMismatch) {
-    // Normal case.  No different than findRRset.
     EXPECT_EQ(DataSrc::ERROR,
     EXPECT_EQ(DataSrc::ERROR,
-              data_source.findExactRRset(www_name, RRClass::CH(), rrtype,
+              data_source.findExactRRset(www_name, rrclass_notmatch, rrtype,
                                          result_sets, find_flags, NULL));
                                          result_sets, find_flags, NULL));
 }
 }
 
 
+TEST_F(Sqlite3DataSourceTest, findExactRRsetClassAny) {
+    checkFind(EXACT, data_source, www_name, &zone_name, RRClass::ANY(), rrclass,
+              rrtype, rrttl, 0, common_a_data, &common_sig_data);
+}
+
 TEST_F(Sqlite3DataSourceTest, findRRsetNSEC3) {
 TEST_F(Sqlite3DataSourceTest, findRRsetNSEC3) {
     // Simple NSEC3 tests (more should be added)
     // Simple NSEC3 tests (more should be added)
     string hashstr("1BB7SO0452U1QHL98UISNDD9218GELR5");
     string hashstr("1BB7SO0452U1QHL98UISNDD9218GELR5");
@@ -792,7 +820,7 @@ TEST_F(Sqlite3DataSourceTest, findExactRRsetCNAME) {
     // This qname only has the CNAME (+ sigs).  In this case it should be
     // This qname only has the CNAME (+ sigs).  In this case it should be
     // no different than findRRset for CNAME query.
     // no different than findRRset for CNAME query.
     rrtype = RRType::CNAME();
     rrtype = RRType::CNAME();
-    checkFind(NORMAL, data_source, qname, &zone_name, rrclass,
+    checkFind(NORMAL, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
               rrtype, rrttl, 0, cname_data, &cname_sig_data);
 
 
     // queries for (ordinary) different RR types that match the CNAME.
     // queries for (ordinary) different RR types that match the CNAME.
@@ -803,15 +831,15 @@ TEST_F(Sqlite3DataSourceTest, findExactRRsetCNAME) {
     ttls.push_back(rrttl);
     ttls.push_back(rrttl);
     answers.push_back(&cname_data);
     answers.push_back(&cname_data);
     signatures.push_back(&cname_sig_data);
     signatures.push_back(&cname_sig_data);
-    checkFind(EXACT, data_source, qname, &zone_name, rrclass,
+    checkFind(EXACT, data_source, qname, &zone_name, rrclass, rrclass,
               rrtype, ttls, DataSrc::TYPE_NOT_FOUND, types, answers,
               rrtype, ttls, DataSrc::TYPE_NOT_FOUND, types, answers,
               signatures);
               signatures);
 }
 }
 
 
-TEST_F(Sqlite3DataSourceTest, findReferralRRset) {
-    // A referral lookup searches for NS, DS, or DNAME, or their sigs.
-    const Name qname("sql1.example.com");
-
+void
+Sqlite3DataSourceTest::findReferralRRsetCommon(const Name& qname,
+                                               const RRClass& qclass)
+{
     types.push_back(RRType::NS());
     types.push_back(RRType::NS());
     types.push_back(RRType::DS());
     types.push_back(RRType::DS());
     ttls.push_back(rrttl);
     ttls.push_back(rrttl);
@@ -822,20 +850,32 @@ TEST_F(Sqlite3DataSourceTest, findReferralRRset) {
     signatures.push_back(&child_ds_sig_data);
     signatures.push_back(&child_ds_sig_data);
     // Note: zone_name matters here because we need to perform the search
     // Note: zone_name matters here because we need to perform the search
     // in the parent zone.
     // in the parent zone.
-    checkFind(REFERRAL, data_source, qname, &zone_name, rrclass,
+    checkFind(REFERRAL, data_source, qname, &zone_name, qclass, rrclass,
               rrtype, ttls, DataSrc::REFERRAL, types, answers, signatures);
               rrtype, ttls, DataSrc::REFERRAL, types, answers, signatures);
 }
 }
+    
+
+TEST_F(Sqlite3DataSourceTest, findReferralRRset) {
+    // A referral lookup searches for NS, DS, or DNAME, or their sigs.
+    const Name qname("sql1.example.com");
+    findReferralRRsetCommon(qname, rrclass);
+}
 
 
 TEST_F(Sqlite3DataSourceTest, findReferralRRsetClassMismatch) {
 TEST_F(Sqlite3DataSourceTest, findReferralRRsetClassMismatch) {
     EXPECT_EQ(DataSrc::ERROR,
     EXPECT_EQ(DataSrc::ERROR,
-              data_source.findReferral(www_name, RRClass::CH(), result_sets,
+              data_source.findReferral(www_name, rrclass_notmatch, result_sets,
                                        find_flags, NULL));
                                        find_flags, NULL));
 }
 }
 
 
+TEST_F(Sqlite3DataSourceTest, findReferralRRsetClassAny) {
+    const Name qname("sql1.example.com");
+    findReferralRRsetCommon(qname, RRClass::ANY());
+}
+
 TEST_F(Sqlite3DataSourceTest, findReferralRRsetDNAME) {
 TEST_F(Sqlite3DataSourceTest, findReferralRRsetDNAME) {
     // same as above.  the DNAME case.
     // same as above.  the DNAME case.
     const Name qname("dname.example.com");
     const Name qname("dname.example.com");
-    checkFind(REFERRAL, data_source, qname, &zone_name, rrclass,
+    checkFind(REFERRAL, data_source, qname, &zone_name, rrclass, rrclass,
               RRType::DNAME(), rrttl, 0, dname_data, &dname_sig_data);
               RRType::DNAME(), rrttl, 0, dname_data, &dname_sig_data);
 }
 }
 
 
@@ -848,16 +888,17 @@ TEST_F(Sqlite3DataSourceTest, findReferralRRsetFail) {
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
 }
 }
 
 
-TEST_F(Sqlite3DataSourceTest, findAddressRRset) {
+void
+Sqlite3DataSourceTest::findAddressRRsetCommon(const RRClass& qclass) {
     // A referral lookup searches for A or AAAA, or their sigs.
     // A referral lookup searches for A or AAAA, or their sigs.
 
 
     // A-only case
     // A-only case
-    checkFind(ADDRESS, data_source, www_name, &zone_name, rrclass,
+    checkFind(ADDRESS, data_source, www_name, &zone_name, qclass, rrclass,
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
               rrtype, rrttl, 0, common_a_data, &common_sig_data);
 
 
     // AAAA-only case
     // AAAA-only case
     checkFind(ADDRESS, data_source, Name("ip6.example.com"), &zone_name,
     checkFind(ADDRESS, data_source, Name("ip6.example.com"), &zone_name,
-              rrclass, RRType::AAAA(), rrttl, 0, common_aaaa_data,
+              qclass, rrclass, RRType::AAAA(), rrttl, 0, common_aaaa_data,
               &common_aaaa_sig_data);
               &common_aaaa_sig_data);
 
 
     // Dual-stack
     // Dual-stack
@@ -869,21 +910,29 @@ TEST_F(Sqlite3DataSourceTest, findAddressRRset) {
     ttls.push_back(rrttl);
     ttls.push_back(rrttl);
     answers.push_back(&common_aaaa_data);
     answers.push_back(&common_aaaa_data);
     signatures.push_back(&common_aaaa_sig_data);
     signatures.push_back(&common_aaaa_sig_data);
-    checkFind(ADDRESS, data_source, Name("ip46.example.com"),
-              &zone_name, rrclass, rrtype, ttls, 0, types, answers, signatures);
+    checkFind(ADDRESS, data_source, Name("ip46.example.com"), &zone_name,
+              rrclass, rrclass, rrtype, ttls, 0, types, answers, signatures);
 
 
     // The qname doesn't have no address records.
     // The qname doesn't have no address records.
     EXPECT_EQ(DataSrc::SUCCESS,
     EXPECT_EQ(DataSrc::SUCCESS,
-              data_source.findAddrs(Name("text.example.com"), rrclass,
+              data_source.findAddrs(Name("text.example.com"), qclass,
                                     result_sets, find_flags, &zone_name));
                                     result_sets, find_flags, &zone_name));
     EXPECT_EQ(DataSrc::TYPE_NOT_FOUND, find_flags);
     EXPECT_EQ(DataSrc::TYPE_NOT_FOUND, find_flags);
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
     EXPECT_TRUE(result_sets.begin() == result_sets.end());
 }
 }
 
 
+TEST_F(Sqlite3DataSourceTest, findAddressRRset) {
+    findAddressRRsetCommon(rrclass);
+}
+
 TEST_F(Sqlite3DataSourceTest, findAddressRRsetClassMismatch) {
 TEST_F(Sqlite3DataSourceTest, findAddressRRsetClassMismatch) {
-    EXPECT_EQ(DataSrc::ERROR, data_source.findAddrs(www_name, RRClass::CH(),
+    EXPECT_EQ(DataSrc::ERROR, data_source.findAddrs(www_name, rrclass_notmatch,
                                                     result_sets, find_flags,
                                                     result_sets, find_flags,
                                                     NULL));
                                                     NULL));
 }
 }
 
 
+TEST_F(Sqlite3DataSourceTest, findAddressRRsetClassAny) {
+    findAddressRRsetCommon(RRClass::ANY());
+}
+
 }
 }

+ 17 - 1
src/lib/auth/tests/test_datasrc.cc

@@ -451,7 +451,7 @@ TestDataSrc::findClosestEnclosure(NameMatch& match,
     const Name& qname = match.qname();
     const Name& qname = match.qname();
     NameComparisonResult::NameRelation cmp;
     NameComparisonResult::NameRelation cmp;
 
 
-    if (qclass != getClass()) {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
         return;
         return;
     }
     }
 
 
@@ -726,6 +726,10 @@ TestDataSrc::findRRset(const Name& qname,
                        uint32_t& flags,
                        uint32_t& flags,
                        const Name* zonename) const
                        const Name* zonename) const
 {
 {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
+        return (ERROR);
+    }
+
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     return (SUCCESS);
     return (SUCCESS);
 }
 }
@@ -738,6 +742,10 @@ TestDataSrc::findExactRRset(const Name& qname,
                             uint32_t& flags,
                             uint32_t& flags,
                             const Name* zonename) const
                             const Name* zonename) const
 {
 {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
+        return (ERROR);
+    }
+
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     findRecords(qname, qtype, target, zonename, NORMAL, flags);
     // Ignore referrals in this case
     // Ignore referrals in this case
     flags &= ~REFERRAL;
     flags &= ~REFERRAL;
@@ -758,6 +766,10 @@ TestDataSrc::findAddrs(const Name& qname,
                        uint32_t& flags,
                        uint32_t& flags,
                        const Name* zonename) const
                        const Name* zonename) const
 {
 {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
+        return (ERROR);
+    }
+
     findRecords(qname, RRType::ANY(), target, zonename, ADDRESS, flags);
     findRecords(qname, RRType::ANY(), target, zonename, ADDRESS, flags);
     return (SUCCESS);
     return (SUCCESS);
 }
 }
@@ -769,6 +781,10 @@ TestDataSrc::findReferral(const Name& qname,
                           uint32_t& flags,
                           uint32_t& flags,
                           const Name* zonename) const
                           const Name* zonename) const
 {
 {
+    if (qclass != getClass() && qclass != RRClass::ANY()) {
+        return (ERROR);
+    }
+
     findRecords(qname, RRType::ANY(), target, zonename, DELEGATION, flags);
     findRecords(qname, RRType::ANY(), target, zonename, DELEGATION, flags);
     return (SUCCESS);
     return (SUCCESS);
 }
 }

+ 0 - 4
src/lib/auth/tests/testdata/q_www

@@ -1,4 +0,0 @@
-# www.example.com/A (normal lookup, positive answer)
-  29 e8 01 00 00 01 00 00 00 00 00 00 03 77 77 77
-  07 65 78 61 6d 70 6c 65 03 63 6f 6d 00 00 01 00
-  01