Browse Source

[1067] "FIX" different TTL instead of throwing

When we iterate and find out that there are RRs in an RRset with
different TTL, we go for the lowest of them instead of throwing and give
a warning.
Michal 'vorner' Vaner 13 years ago
parent
commit
fe8f331430

+ 6 - 2
src/lib/datasrc/database.cc

@@ -352,8 +352,12 @@ public:
         RRsetPtr rrset(new RRset(name, class_, rtype, RRTTL(ttl)));
         while (data_ready_ && name_ == name_str && rtype_str == rtype_) {
             if (ttl_ != ttl) {
-                isc_throw(DataSourceError, "TTLs in rrset " + name_str + "/" +
-                          rtype_str + " differ");
+                LOG_WARN(logger, DATASRC_DATABASE_ITERATE_TTL_DIFF).
+                    arg(name_).arg(ttl).arg(ttl_);
+                if (ttl < ttl_) {
+                    ttl_ = ttl;
+                    rrset->setTTL(RRTTL(ttl));
+                }
             }
             rrset->addRdata(rdata::createRdata(rtype, class_, rdata_));
             getData();

+ 7 - 0
src/lib/datasrc/datasrc_messages.mes

@@ -114,6 +114,13 @@ While iterating through the zone, the program reached end of the data.
 While iterating through the zone, the program extracted next RRset from it.
 The name and RRtype of the RRset is indicated in the message.
 
+% DATASRC_DATABASE_ITERATE_TTL_DIFF TTL for %1/%2 differs (%3 and %4)
+While iterating through the zone, the time to live for RRs of the given RRset
+was discovered not to be the same the same This isn't allowed on the wire and
+is considered generally broken, so we set it to the lowest of them internaly
+(but we don't modify the database). But the data in database should better be
+checked and fixed by human.
+
 % DATASRC_DO_QUERY handling query for '%1/%2'
 A debug message indicating that a query for the given name and RR type is being
 processed.

+ 2 - 1
src/lib/datasrc/tests/database_unittest.cc

@@ -554,8 +554,9 @@ TEST_F(DatabaseClientTest, iterator) {
 // This has inconsistent TTL in the set (the rest, like nonsense in
 // the data is handled in rdata itself).
 TEST_F(DatabaseClientTest, badIterator) {
+    // It should not throw, but get the lowest one of them
     ZoneIteratorPtr it(client_->getIterator(Name("bad.example.org")));
-    EXPECT_THROW(it->getNextRRset(), DataSourceError);
+    EXPECT_EQ(it->getNextRRset()->getTTL(), isc::dns::RRTTL(300));
 }
 
 // checks if the given rrset matches the