|
@@ -13,10 +13,14 @@
|
|
|
// PERFORMANCE OF THIS SOFTWARE.
|
|
|
|
|
|
#include <datasrc/memory/zone_data_loader.h>
|
|
|
+#include <datasrc/memory/logger.h>
|
|
|
+#include <datasrc/memory/segment_object_holder.h>
|
|
|
|
|
|
#include <dns/rdataclass.h>
|
|
|
+#include <dns/masterload.h>
|
|
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
+#include <boost/bind.hpp>
|
|
|
|
|
|
using namespace isc::dns;
|
|
|
using namespace isc::dns::rdata;
|
|
@@ -25,6 +29,8 @@ namespace isc {
|
|
|
namespace datasrc {
|
|
|
namespace memory {
|
|
|
|
|
|
+using detail::SegmentObjectHolder;
|
|
|
+
|
|
|
void
|
|
|
ZoneDataLoader::addFromLoad(const ConstRRsetPtr& rrset) {
|
|
|
// If we see a new name, flush the temporary holders, adding the
|
|
@@ -103,6 +109,96 @@ ZoneDataLoader::getCurrentName() const {
|
|
|
return (node_rrsigsets_.begin()->second->getName());
|
|
|
}
|
|
|
|
|
|
+namespace { // unnamed namespace
|
|
|
+
|
|
|
+// A functor type used for loading.
|
|
|
+typedef boost::function<void(isc::dns::ConstRRsetPtr)> LoadCallback;
|
|
|
+
|
|
|
+ZoneData*
|
|
|
+loadZoneDataInternal(util::MemorySegment& mem_sgmt,
|
|
|
+ const isc::dns::RRClass rrclass,
|
|
|
+ const Name& zone_name,
|
|
|
+ boost::function<void(LoadCallback)> rrset_installer)
|
|
|
+{
|
|
|
+ SegmentObjectHolder<ZoneData, RRClass> holder(
|
|
|
+ mem_sgmt, ZoneData::create(mem_sgmt, zone_name), rrclass);
|
|
|
+
|
|
|
+ ZoneDataLoader loader(mem_sgmt, rrclass, zone_name, *holder.get());
|
|
|
+ rrset_installer(boost::bind(&ZoneDataLoader::addFromLoad, &loader, _1));
|
|
|
+ // Add any last RRsets that were left
|
|
|
+ loader.flushNodeRRsets();
|
|
|
+
|
|
|
+ const ZoneNode* origin_node = holder.get()->getOriginNode();
|
|
|
+ const RdataSet* rdataset = origin_node->getData();
|
|
|
+ // If the zone is NSEC3-signed, check if it has NSEC3PARAM
|
|
|
+ if (holder.get()->isNSEC3Signed()) {
|
|
|
+ if (RdataSet::find(rdataset, RRType::NSEC3PARAM()) == NULL) {
|
|
|
+ LOG_WARN(logger, DATASRC_MEMORY_MEM_NO_NSEC3PARAM).
|
|
|
+ arg(zone_name).arg(rrclass);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // When an empty zone file is loaded, the origin doesn't even have
|
|
|
+ // an SOA RR. This condition should be avoided, and hence load()
|
|
|
+ // should throw when an empty zone is loaded.
|
|
|
+ if (RdataSet::find(rdataset, RRType::SOA()) == NULL) {
|
|
|
+ isc_throw(EmptyZone,
|
|
|
+ "Won't create an empty zone for: " << zone_name);
|
|
|
+ }
|
|
|
+
|
|
|
+ return (holder.release());
|
|
|
+}
|
|
|
+
|
|
|
+// A wrapper for dns::masterLoad used by load() below. Essentially it
|
|
|
+// converts the two callback types. Note the mostly redundant wrapper of
|
|
|
+// boost::bind. It converts function<void(ConstRRsetPtr)> to
|
|
|
+// function<void(RRsetPtr)> (masterLoad() expects the latter). SunStudio
|
|
|
+// doesn't seem to do this conversion if we just pass 'callback'.
|
|
|
+void
|
|
|
+masterLoadWrapper(const char* const filename, const Name& origin,
|
|
|
+ const RRClass& zone_class,
|
|
|
+ LoadCallback callback)
|
|
|
+{
|
|
|
+ masterLoad(filename, origin, zone_class, boost::bind(callback, _1));
|
|
|
+}
|
|
|
+
|
|
|
+// The installer called from load() for the iterator version of load().
|
|
|
+void
|
|
|
+generateRRsetFromIterator(ZoneIterator* iterator,
|
|
|
+ LoadCallback callback)
|
|
|
+{
|
|
|
+ ConstRRsetPtr rrset;
|
|
|
+ while ((rrset = iterator->getNextRRset()) != NULL) {
|
|
|
+ callback(rrset);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+} // end of unnamed namespace
|
|
|
+
|
|
|
+ZoneData*
|
|
|
+loadZoneData(util::MemorySegment& mem_sgmt,
|
|
|
+ const isc::dns::RRClass rrclass,
|
|
|
+ const isc::dns::Name& zone_name,
|
|
|
+ const std::string& zone_file)
|
|
|
+{
|
|
|
+ return (loadZoneDataInternal(mem_sgmt, rrclass, zone_name,
|
|
|
+ boost::bind(masterLoadWrapper,
|
|
|
+ zone_file.c_str(),
|
|
|
+ zone_name, rrclass,
|
|
|
+ _1)));
|
|
|
+}
|
|
|
+
|
|
|
+ZoneData*
|
|
|
+loadZoneData(util::MemorySegment& mem_sgmt,
|
|
|
+ const isc::dns::RRClass rrclass,
|
|
|
+ const isc::dns::Name& zone_name,
|
|
|
+ ZoneIterator& iterator)
|
|
|
+{
|
|
|
+ return (loadZoneDataInternal(mem_sgmt, rrclass, zone_name,
|
|
|
+ boost::bind(generateRRsetFromIterator,
|
|
|
+ &iterator, _1)));
|
|
|
+}
|
|
|
+
|
|
|
} // namespace memory
|
|
|
} // namespace datasrc
|
|
|
} // namespace isc
|