Browse Source

[trac1062] initial support for RRSIGS for matches and CNAME

Jelte Jansen 13 years ago
parent
commit
bc281e8b48

+ 22 - 0
src/lib/datasrc/database.cc

@@ -18,6 +18,8 @@
 #include <dns/name.h>
 #include <dns/rrttl.h>
 #include <dns/rdata.h>
+#include <dns/rdataclass.h>
+
 #include <datasrc/data_source.h>
 
 using isc::dns::Name;
@@ -123,6 +125,26 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
                                                                 getClass(),
                                                                 columns[3]));
             result_status = CNAME;
+        } else if (cur_type == isc::dns::RRType::RRSIG()) {
+            isc::dns::rdata::RdataPtr cur_rrsig(
+                isc::dns::rdata::createRdata(cur_type, getClass(), columns[3]));
+            const isc::dns::RRType& type_covered =
+                static_cast<isc::dns::rdata::generic::RRSIG*>(
+                    cur_rrsig.get())->typeCovered();
+            // Ignore the RRSIG data we got if it does not cover the type
+            // that was requested or CNAME
+            // see if we have RRset data yet, and whether it has an RRsig yet
+            if (type_covered == type || type_covered == isc::dns::RRType::CNAME()) {
+                if (!result_rrset) {
+                // no data at all yet, assume the RRset data is coming, and
+                // that the type covered will match
+                    result_rrset = isc::dns::RRsetPtr(new isc::dns::RRset(name,
+                                                                        getClass(),
+                                                                        type_covered,
+                                                                        cur_ttl));
+                }
+                result_rrset->addRRsig(cur_rrsig);
+            }
         }
     }
 

+ 5 - 0
src/lib/datasrc/database.h

@@ -157,6 +157,11 @@ public:
 
         /**
          * \brief Find an RRset in the datasource
+         *
+         * target is unused at this point, it was used in the original
+         * API to store the results for ANY queries, and we may reuse it
+         * for that, but we might choose a different approach.
+         * 
          */
         virtual FindResult find(const isc::dns::Name& name,
                                 const isc::dns::RRType& type,

+ 49 - 0
src/lib/datasrc/tests/database_unittest.cc

@@ -98,6 +98,7 @@ private:
     }
 
     void fillData() {
+        // some plain data
         addRecord("A", "3600", "", "192.0.2.1");
         addRecord("AAAA", "3600", "", "2001:db8::1");
         addRecord("AAAA", "3600", "", "2001:db8::2");
@@ -105,6 +106,27 @@ private:
         addRecord("CNAME", "3600", "", "www.example.org.");
         addCurName("cname.example.org.");
 
+        // some DNSSEC-'signed' data
+        addRecord("A", "3600", "", "192.0.2.1");
+        addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
+        addRecord("AAAA", "3600", "", "2001:db8::1");
+        addRecord("AAAA", "3600", "", "2001:db8::2");
+        addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
+        addCurName("signed1.example.org.");
+
+        // let's pretend we have a database that is not careful
+        // about the order in which it returns data
+        addRecord("RRSIG", "3600", "", "A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
+        addRecord("AAAA", "3600", "", "2001:db8::2");
+        addRecord("A", "3600", "", "192.0.2.1");
+        addRecord("RRSIG", "3600", "", "AAAA 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
+        addRecord("AAAA", "3600", "", "2001:db8::1");
+        addCurName("signed2.example.org.");
+
+        addRecord("CNAME", "3600", "", "www.example.org.");
+        addRecord("RRSIG", "3600", "", "CNAME 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE");
+        addCurName("signedcname.example.org.");
+
         // also add some intentionally bad data
         cur_name.push_back(std::vector<std::string>());
         addCurName("emptyvector.example.org.");
@@ -183,12 +205,14 @@ TEST_F(DatabaseClientTest, find) {
     ASSERT_EQ(ZoneFinder::SUCCESS, result1.code);
     EXPECT_EQ(1, result1.rrset->getRdataCount());
     EXPECT_EQ(isc::dns::RRType::A(), result1.rrset->getType());
+    EXPECT_EQ(isc::dns::RRsetPtr(), result1.rrset->getRRsig());
 
     ZoneFinder::FindResult result2 = finder->find(name, isc::dns::RRType::AAAA(),
                                                   NULL, ZoneFinder::FIND_DEFAULT);
     ASSERT_EQ(ZoneFinder::SUCCESS, result2.code);
     EXPECT_EQ(2, result2.rrset->getRdataCount());
     EXPECT_EQ(isc::dns::RRType::AAAA(), result2.rrset->getType());
+    EXPECT_EQ(isc::dns::RRsetPtr(), result2.rrset->getRRsig());
 
     ZoneFinder::FindResult result3 = finder->find(name, isc::dns::RRType::TXT(),
                                                   NULL, ZoneFinder::FIND_DEFAULT);
@@ -201,6 +225,7 @@ TEST_F(DatabaseClientTest, find) {
     ASSERT_EQ(ZoneFinder::CNAME, result4.code);
     EXPECT_EQ(1, result4.rrset->getRdataCount());
     EXPECT_EQ(isc::dns::RRType::CNAME(), result4.rrset->getType());
+    EXPECT_EQ(isc::dns::RRsetPtr(), result4.rrset->getRRsig());
 
     ZoneFinder::FindResult result5 = finder->find(isc::dns::Name("doesnotexist.example.org."),
                                                   isc::dns::RRType::A(),
@@ -208,6 +233,30 @@ TEST_F(DatabaseClientTest, find) {
     ASSERT_EQ(ZoneFinder::NXDOMAIN, result5.code);
     EXPECT_EQ(isc::dns::ConstRRsetPtr(), result5.rrset);
 
+    ZoneFinder::FindResult result6 = finder->find(isc::dns::Name("signed1.example.org."),
+                                                  isc::dns::RRType::A(),
+                                                  NULL, ZoneFinder::FIND_DEFAULT);
+    ASSERT_EQ(ZoneFinder::SUCCESS, result6.code);
+    EXPECT_EQ(1, result6.rrset->getRdataCount());
+    EXPECT_EQ(isc::dns::RRType::A(), result6.rrset->getType());
+    EXPECT_NE(isc::dns::RRsetPtr(), result6.rrset->getRRsig());
+
+    ZoneFinder::FindResult result7 = finder->find(isc::dns::Name("signed1.example.org."),
+                                                  isc::dns::RRType::AAAA(),
+                                                  NULL, ZoneFinder::FIND_DEFAULT);
+    ASSERT_EQ(ZoneFinder::SUCCESS, result7.code);
+    EXPECT_EQ(2, result7.rrset->getRdataCount());
+    EXPECT_EQ(isc::dns::RRType::AAAA(), result7.rrset->getType());
+    EXPECT_NE(isc::dns::RRsetPtr(), result7.rrset->getRRsig());
+
+    ZoneFinder::FindResult result8 = finder->find(isc::dns::Name("signedcname.example.org."),
+                                                  isc::dns::RRType::A(),
+                                                  NULL, ZoneFinder::FIND_DEFAULT);
+    ASSERT_EQ(ZoneFinder::SUCCESS, result8.code);
+    EXPECT_EQ(1, result8.rrset->getRdataCount());
+    EXPECT_EQ(isc::dns::RRType::CNAME(), result8.rrset->getType());
+    EXPECT_NE(isc::dns::RRsetPtr(), result8.rrset->getRRsig());
+
     EXPECT_THROW(finder->find(isc::dns::Name("emptyvector.example.org."),
                                               isc::dns::RRType::A(),
                                               NULL, ZoneFinder::FIND_DEFAULT),

+ 5 - 0
src/lib/dns/rdata/generic/rrsig_46.cc

@@ -243,5 +243,10 @@ RRSIG::compare(const Rdata& other) const {
     }
 }
 
+const RRType&
+RRSIG::typeCovered() {
+    return impl_->covered_;
+}
+
 // END_RDATA_NAMESPACE
 // END_ISC_NAMESPACE

+ 3 - 0
src/lib/dns/rdata/generic/rrsig_46.h

@@ -38,6 +38,9 @@ public:
     // END_COMMON_MEMBERS
     RRSIG& operator=(const RRSIG& source);
     ~RRSIG();
+
+    // specialized methods
+    const RRType& typeCovered();
 private:
     RRSIGImpl* impl_;
 };