result == ZoneTree::ALREADYEXISTS) && node != NULL);
}
+namespace {
+// A helper to convert a TTL value in network byte order and set it in
+// ZoneData::min_ttl_. We can use util::OutputBuffer, but copy the logic
+// here to guarantee it is exception free.
+void
+setTTLInNetOrder(uint32_t val, uint32_t* result) {
+ uint8_t buf[4];
+ buf[0] = static_cast<uint8_t>((val & 0xff000000) >> 24);
+ buf[1] = static_cast<uint8_t>((val & 0x00ff0000) >> 16);
+ buf[2] = static_cast<uint8_t>((val & 0x0000ff00) >> 8);
+ buf[3] = static_cast<uint8_t>(val & 0x000000ff);
+ std::memcpy(result, buf, sizeof(*result));
+}
+}
+
+ZoneData::ZoneData(ZoneTree* zone_tree, ZoneNode* origin_node) :
+ zone_tree_(zone_tree), origin_node_(origin_node),
+ min_ttl_(0) // tentatively set to silence static checkers
+{
+ setTTLInNetOrder(RRTTL::MAX_TTL().getValue(), &min_ttl_);
+}
+
ZoneData*
ZoneData::create(util::MemorySegment& mem_sgmt, const Name& zone_origin) {
// ZoneTree::insert() and ZoneData allocation can throw. See also
result == ZoneTree::ALREADYEXISTS) && node != NULL);
}
+void
+ZoneData::setMinTTL(uint32_t min_ttl_val) {
+ setTTLInNetOrder(min_ttl_val, &min_ttl_);
+}
+
} // namespace memory
} // namespace datasrc
} // datasrc isc
/// from NSEC to NSEC3 or vice versa, support incremental signing, or support
/// multiple sets of NSEC3 parameters.
///
-/// One last type of meta data is the status of the zone in terms of DNSSEC
+/// One other type of meta data is the status of the zone in terms of DNSSEC
/// signing. This class supports the following concepts:
/// - Whether the zone is signed or not, either with NSEC records or NSEC3
/// records.
/// because we won't have to change the application code when we implement
/// the future separation.
///
+/// One last type of meta data is the zone's "minimum" TTL. It's expected
+/// to be a shortcut copy of the minimum field of the zone's SOA RDATA,
+/// and is expected to be used to create an SOA RR for a negative response,
+/// whose RR TTL may have to be set to this value according to RFC2308.
+/// This class is not aware of such usage, however, and only provides a
+/// simple getter and setter method for this value: \c getMinTTLData() and
+/// \c setMinTTL(). The user of this class is responsible for setting the
+/// value with \c setMinTTL() when it loads or updates the SOA RR.
+///
/// The intended usage of these two status concepts is to implement the
/// \c ZoneFinder::Context::isNSECSigned() and
/// \c ZoneFinder::Context::isNSEC3Signed() methods. A possible implementation
/// allocator (\c create()), so the constructor is hidden as private.
///
/// It never throws an exception.
- ZoneData(ZoneTree* zone_tree, ZoneNode* origin_node) :
- zone_tree_(zone_tree), origin_node_(origin_node)
- {}
+ ZoneData(ZoneTree* zone_tree, ZoneNode* origin_node);
// Zone node flags.
private:
///
/// \throw none
const NSEC3Data* getNSEC3Data() const { return (nsec3_data_.get()); }
+
+ /// \brief Return a pointer to the zone's minimum TTL data.
+ ///
+ /// The returned pointer points to a memory region that is valid at least
+ /// for 32 bits, storing the zone's minimum TTL in the network byte
+ /// order. The corresponding 32-bit value as an integer is initially
+ /// set to the value of \c dns::RRTTL::MAX_TTL(), and, once
+ /// \c setMinTTL() is called, set to the value specified at the latest
+ /// call to \c setMinTTL().
+ ///
+ /// It returns opaque data to make it clear that unless the wire
+ /// format data is necessary (e.g., when rendering it in a DNS message),
+ /// it should be converted to, e.g., an \c RRTTL object explicitly.
+ ///
+ /// The returned pointer is valid as long as the \c ZoneData is valid,
+ /// and the corresponding 32-bit data are the same until \c setMinTTL()
+ /// is called.
+ ///
+ /// \throw none
+ const void* getMinTTLData() const { return (&min_ttl_); }
//@}
///
nsec3_data_ = nsec3_data;
return (old);
}
+
+ /// \brief Set the zone's "minimum" TTL.
+ ///
+ /// This method updates the recorded minimum TTL of the zone data.
+ /// It's expected to be identical to the value of the Minimum field
+ /// of the SOA RR at the zone apex, but this method does not check the
+ /// consistency; it's the caller's responsibility.
+ ///
+ /// While RFC2181 specifies the max TTL value to be 2^31-1, this method
+ /// does not check the range; it accepts any unsigned 32-bit integer
+ /// value. In practice, this shouldn't cause a problem, however, because
+ /// the only expected usage of this value is to use the minimum of this
+ /// value and SOA RR's TTL, and the latter is expected to be in the
+ /// valid range.
+ ///
+ /// \throw None
+ /// \param min_ttl_val The minimum TTL value as unsigned 32-bit integer
+ /// in the host byte order.
+ void setMinTTL(uint32_t min_ttl_val);
//@}
private:
const boost::interprocess::offset_ptr<ZoneTree> zone_tree_;
const boost::interprocess::offset_ptr<ZoneNode> origin_node_;
boost::interprocess::offset_ptr<NSEC3Data> nsec3_data_;
+ uint32_t min_ttl_;
};
} // namespace memory
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#include <datasrc/memory/zone_data.h>
+#include <datasrc/memory/rdata_serialization.h>
+#include <datasrc/memory/rdataset.h>
+
#include "memory_segment_test.h"
#include <dns/rdataclass.h>
#include <exceptions/exceptions.h>
+#include <util/buffer.h>
+
#include <dns/name.h>
#include <dns/labelsequence.h>
#include <dns/rrclass.h>
-
-#include <datasrc/memory/rdata_serialization.h>
-#include <datasrc/memory/rdataset.h>
-#include <datasrc/memory/zone_data.h>
+#include <dns/rrttl.h>
#include <testutils/dnsmessage_test.h>
zone_data_->setSigned(false);
EXPECT_FALSE(zone_data_->isSigned());
}
+
+// A simple wrapper to reconstruct an RRTTL object from wire-format TTL
+// data (32 bits)
+RRTTL
+createRRTTL(const void* ttl_data) {
+ isc::util::InputBuffer b(ttl_data, sizeof(uint32_t));
+ return (RRTTL(b));
+}
+
+TEST_F(ZoneDataTest, minTTL) {
+ // By default it's tentatively set to "max TTL"
+ EXPECT_EQ(RRTTL::MAX_TTL(), createRRTTL(zone_data_->getMinTTLData()));
+
+ // Explicitly set, then retrieve it.
+ zone_data_->setMinTTL(1200);
+ EXPECT_EQ(RRTTL(1200), createRRTTL(zone_data_->getMinTTLData()));
+}
}