18 #include <boost/bind.hpp> 19 #include <boost/lexical_cast.hpp> 23 using boost::lexical_cast;
31 zoneText(
const Name& zone_name,
const RRClass& zone_class) {
32 return (zone_name.toText(
true) +
"/" + zone_class.toText());
36 checkSOA(
const Name& zone_name,
const RRClass& zone_class,
37 const RRsetCollectionBase& zone_rrsets,
38 ZoneCheckerCallbacks& callback) {
40 zone_rrsets.find(zone_name, zone_class,
RRType::SOA());
45 rit->next(), ++count) {
46 if (dynamic_cast<const rdata::generic::SOA*>(&rit->getCurrent()) ==
48 isc_throw(Unexpected,
"Zone checker found bad RDATA in SOA");
53 isc_throw(Unexpected,
"Zone checker found an empty SOA RRset");
57 callback.error(
"zone " + zoneText(zone_name, zone_class) +
": has " +
58 lexical_cast<string>(count) +
" SOA records");
67 findZoneCut(
const Name& zone_name,
const RRClass& zone_class,
68 const RRsetCollectionBase& zone_rrsets,
const Name& target_name) {
69 const unsigned int origin_count = zone_name.getLabelCount();
70 const unsigned int target_count = target_name.getLabelCount();
71 assert(origin_count <= target_count);
73 for (
unsigned int l = origin_count; l <= target_count; ++l) {
74 const Name& mid_name = (l == target_count) ? target_name :
75 target_name.split(target_count - l);
78 if (l != origin_count &&
79 (found = zone_rrsets.find(mid_name, zone_class,
RRType::NS())) !=
83 if (l != target_count &&
84 (found = zone_rrsets.find(mid_name, zone_class,
RRType::DNAME()))
95 checkNSNames(
const Name& zone_name,
const RRClass& zone_class,
96 const RRsetCollectionBase& zone_rrsets,
98 if (ns_rrset->getRdataCount() == 0) {
100 isc_throw(Unexpected,
"Zone checker found an empty NS RRset");
106 const rdata::generic::NS* ns_data =
107 dynamic_cast<const rdata::generic::NS*>(&rit->getCurrent());
108 if (ns_data == NULL) {
109 isc_throw(Unexpected,
"Zone checker found bad RDATA in NS");
111 const Name& ns_name = ns_data->getNSName();
113 ns_name.compare(zone_name).getRelation();
121 zone_rrsets, ns_name);
126 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
127 ": NS '" + ns_name.toText(
true) +
"' is " +
129 cut_rrset->getName().toText(
true) +
130 "' (illegal per RFC6672)");
136 if (zone_rrsets.find(ns_name, zone_class,
RRType::CNAME()) != NULL) {
137 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
138 ": NS '" + ns_name.toText(
true) +
"' is a CNAME " +
139 "(illegal per RFC2181)");
142 if (zone_rrsets.find(ns_name, zone_class,
RRType::A()) == NULL &&
143 zone_rrsets.find(ns_name, zone_class,
RRType::AAAA()) == NULL) {
144 callbacks.warn(
"zone " + zoneText(zone_name, zone_class) +
145 ": NS has no address records (A or AAAA)");
151 checkNS(
const Name& zone_name,
const RRClass& zone_class,
152 const RRsetCollectionBase& zone_rrsets,
153 ZoneCheckerCallbacks& callbacks) {
155 zone_rrsets.find(zone_name, zone_class,
RRType::NS());
157 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
158 ": has no NS records");
161 checkNSNames(zone_name, zone_class, zone_rrsets, rrset, callbacks);
167 errorWrapper(
const string& reason,
const ZoneCheckerCallbacks* callbacks,
170 callbacks->error(reason);
178 bool had_error =
false;
180 boost::bind(errorWrapper, _1, &callbacks, &had_error),
183 checkSOA(zone_name, zone_class, zone_rrsets, my_callbacks);
184 checkNS(zone_name, zone_class, zone_rrsets, my_callbacks);
The Name class encapsulates DNS names.
static const RRType & CNAME()
bool checkZone(const Name &zone_name, const RRClass &zone_class, const RRsetCollectionBase &zone_rrsets, const ZoneCheckerCallbacks &callbacks)
Perform basic integrity checks on zone RRsets.
static const RRType & SOA()
void warn(const std::string &reason) const
Call the callback for a non critical issue.
Set of callbacks used in zone checks.
static const RRType & NS()
The RRClass class encapsulates DNS resource record classes.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
static const RRType & A()
Defines the logger used by the top-level component of kea-dhcp-ddns.
static const RRType & DNAME()
boost::shared_ptr< RdataIterator > RdataIteratorPtr
A pointer-like type point to an RdataIterator object.
boost::shared_ptr< const AbstractRRset > ConstRRsetPtr
A pointer-like type pointing to an (immutable) RRset object.
NameRelation
The relation of two names under comparison.
static const RRType & AAAA()
Generic class to represent a set of RRsets.