summaryrefslogtreecommitdiffstats
path: root/src/lib/dns/masterload.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dns/masterload.cc')
-rw-r--r--src/lib/dns/masterload.cc100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/lib/dns/masterload.cc b/src/lib/dns/masterload.cc
new file mode 100644
index 0000000..94638c1
--- /dev/null
+++ b/src/lib/dns/masterload.cc
@@ -0,0 +1,100 @@
+// Copyright (C) 2010-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <dns/masterload.h>
+#include <dns/master_loader.h>
+#include <dns/name.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
+#include <dns/rrclass.h>
+#include <dns/rrset.h>
+#include <dns/rrttl.h>
+#include <dns/rrtype.h>
+#include <dns/rrcollator.h>
+#include <exceptions/exceptions.h>
+
+#include <boost/scoped_ptr.hpp>
+
+#include <functional>
+#include <istream>
+#include <fstream>
+#include <sstream>
+#include <string>
+#include <cctype>
+#include <cerrno>
+
+using namespace isc::dns::rdata;
+
+using namespace std;
+namespace ph = std::placeholders;
+
+namespace isc {
+namespace dns {
+namespace {
+void
+callbackWrapper(const RRsetPtr& rrset, MasterLoadCallback callback,
+ const Name* origin)
+{
+ // Origin related validation:
+ // - reject out-of-zone data
+ // - reject SOA whose owner is not at the top of zone
+ const NameComparisonResult cmp_result =
+ rrset->getName().compare(*origin);
+ if (cmp_result.getRelation() != NameComparisonResult::EQUAL &&
+ cmp_result.getRelation() != NameComparisonResult::SUBDOMAIN) {
+ isc_throw(MasterLoadError, "Out-of-zone data for " << *origin
+ << "/" << rrset->getClass() << ": " << rrset->getName());
+ }
+ if (rrset->getType() == RRType::SOA() &&
+ cmp_result.getRelation() != NameComparisonResult::EQUAL) {
+ isc_throw(MasterLoadError, "SOA not at top of zone: "
+ << *rrset);
+ }
+
+ callback(rrset);
+}
+
+template <typename InputType>
+void
+loadHelper(InputType input, const Name& origin,
+ const RRClass& zone_class, MasterLoadCallback callback)
+{
+ RRCollator rr_collator(std::bind(callbackWrapper, ph::_1, callback,
+ &origin));
+ MasterLoader loader(input, origin, zone_class,
+ MasterLoaderCallbacks::getNullCallbacks(),
+ rr_collator.getCallback());
+ try {
+ loader.load();
+ } catch (const MasterLoaderError& ex) {
+ isc_throw(MasterLoadError, ex.what());
+ }
+ rr_collator.flush();
+}
+}
+
+void
+masterLoad(const char* const filename, const Name& origin,
+ const RRClass& zone_class, MasterLoadCallback callback)
+{
+ if ((filename == NULL) || (*filename == '\0')) {
+ isc_throw(MasterLoadError, "Name of master file must not be null");
+ }
+
+ loadHelper<const char*>(filename, origin, zone_class, callback);
+}
+
+void
+masterLoad(istream& input, const Name& origin, const RRClass& zone_class,
+ MasterLoadCallback callback, const char*)
+{
+ loadHelper<istream&>(input, origin, zone_class, callback);
+}
+
+} // namespace dns
+} // namespace isc