18 #include <boost/lexical_cast.hpp>
23 using boost::lexical_cast;
25 namespace ph = std::placeholders;
32 zoneText(
const Name& zone_name,
const RRClass& zone_class) {
33 return (zone_name.toText(
true) +
"/" + zone_class.toText());
37 checkSOA(
const Name& zone_name,
const RRClass& zone_class,
38 const RRsetCollectionBase& zone_rrsets,
39 ZoneCheckerCallbacks& callback) {
41 zone_rrsets.find(zone_name, zone_class,
RRType::SOA());
46 rit->next(), ++count) {
47 if (dynamic_cast<const rdata::generic::SOA*>(&rit->getCurrent()) ==
49 isc_throw(Unexpected,
"Zone checker found bad RDATA in SOA");
54 isc_throw(Unexpected,
"Zone checker found an empty SOA RRset");
58 callback.error(
"zone " + zoneText(zone_name, zone_class) +
": has " +
59 lexical_cast<string>(count) +
" SOA records");
68 findZoneCut(
const Name& zone_name,
const RRClass& zone_class,
69 const RRsetCollectionBase& zone_rrsets,
const Name& target_name) {
70 const unsigned int origin_count = zone_name.getLabelCount();
71 const unsigned int target_count = target_name.getLabelCount();
72 assert(origin_count <= target_count);
74 for (
unsigned int l = origin_count; l <= target_count; ++l) {
75 const Name& mid_name = (l == target_count) ? target_name :
76 target_name.split(target_count - l);
79 if (l != origin_count &&
80 (found = zone_rrsets.find(mid_name, zone_class,
RRType::NS())) !=
84 if (l != target_count &&
85 (found = zone_rrsets.find(mid_name, zone_class,
RRType::DNAME()))
96 checkNSNames(
const Name& zone_name,
const RRClass& zone_class,
97 const RRsetCollectionBase& zone_rrsets,
99 if (ns_rrset->getRdataCount() == 0) {
101 isc_throw(Unexpected,
"Zone checker found an empty NS RRset");
107 const rdata::generic::NS* ns_data =
108 dynamic_cast<const rdata::generic::NS*
>(&rit->getCurrent());
109 if (ns_data == NULL) {
110 isc_throw(Unexpected,
"Zone checker found bad RDATA in NS");
112 const Name& ns_name = ns_data->getNSName();
114 ns_name.compare(zone_name).getRelation();
122 zone_rrsets, ns_name);
127 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
128 ": NS '" + ns_name.toText(
true) +
"' is " +
130 cut_rrset->getName().toText(
true) +
131 "' (illegal per RFC6672)");
137 if (zone_rrsets.find(ns_name, zone_class,
RRType::CNAME()) != NULL) {
138 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
139 ": NS '" + ns_name.toText(
true) +
"' is a CNAME " +
140 "(illegal per RFC2181)");
143 if (zone_rrsets.find(ns_name, zone_class,
RRType::A()) == NULL &&
144 zone_rrsets.find(ns_name, zone_class,
RRType::AAAA()) == NULL) {
145 callbacks.warn(
"zone " + zoneText(zone_name, zone_class) +
146 ": NS has no address records (A or AAAA)");
152 checkNS(
const Name& zone_name,
const RRClass& zone_class,
153 const RRsetCollectionBase& zone_rrsets,
154 ZoneCheckerCallbacks& callbacks) {
156 zone_rrsets.find(zone_name, zone_class,
RRType::NS());
158 callbacks.error(
"zone " + zoneText(zone_name, zone_class) +
159 ": has no NS records");
162 checkNSNames(zone_name, zone_class, zone_rrsets, rrset, callbacks);
168 errorWrapper(
const string& reason,
const ZoneCheckerCallbacks* callbacks,
171 callbacks->error(reason);
179 bool had_error =
false;
181 std::bind(errorWrapper, ph::_1, &callbacks, &had_error),
184 checkSOA(zone_name, zone_class, zone_rrsets, my_callbacks);
185 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()
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()
void warn(const std::string &reason) const
Call the callback for a non critical issue.
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.