mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 13:37:55 +00:00
[1535] make ZoneFinder::find throw on out-of-zone query
Added new OutOfZoneFind exception, which is thrown (instead of NXDOMAIN result) when zonefinder::find() is called for an out-of-zone name (normally this should not happen; the zonefinder object is itself the result of a call to findZone()
This commit is contained in:
parent
58283fa48a
commit
f8c0d29e25
@ -865,7 +865,8 @@ DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
|
||||
name.compare(getOrigin()).getRelation();
|
||||
if (reln != NameComparisonResult::SUBDOMAIN &&
|
||||
reln != NameComparisonResult::EQUAL) {
|
||||
return (ResultContext(NXDOMAIN, ConstRRsetPtr()));
|
||||
isc_throw(OutOfZoneFind, "out-of-zone find(): " << name.toText() <<
|
||||
" not in " << getOrigin().toText());
|
||||
}
|
||||
|
||||
// First, go through all superdomains from the origin down, searching for
|
||||
|
@ -1202,6 +1202,15 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
|
||||
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name).
|
||||
arg(type);
|
||||
|
||||
const NameComparisonResult::NameRelation reln =
|
||||
name.compare(origin_).getRelation();
|
||||
if (reln != NameComparisonResult::SUBDOMAIN &&
|
||||
reln != NameComparisonResult::EQUAL) {
|
||||
isc_throw(OutOfZoneFind, "out-of-zone find(): " <<
|
||||
name.toText() <<
|
||||
" not in " << origin_.toText());
|
||||
}
|
||||
|
||||
// Get the node. All other cases than an exact match are handled
|
||||
// in findNode(). We simply construct a result structure and return.
|
||||
const ZoneData::FindNodeResult node_result =
|
||||
|
@ -1877,33 +1877,31 @@ TYPED_TEST(DatabaseClientTest, findOutOfZone) {
|
||||
vector<ConstRRsetPtr> target;
|
||||
|
||||
// Superdomain
|
||||
doFindTest(*finder, Name("org"), this->qtype_, this->qtype_,
|
||||
this->rrttl_, ZoneFinder::NXDOMAIN,
|
||||
this->empty_rdatas_, this->empty_rdatas_);
|
||||
EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->findAll(Name("org"), target)->code);
|
||||
EXPECT_THROW(finder->find(Name("org"), this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
EXPECT_THROW(finder->findAll(Name("org"), target), OutOfZoneFind);
|
||||
|
||||
// sharing a common ancestor
|
||||
doFindTest(*finder, Name("noexample.org"), this->qtype_, this->qtype_,
|
||||
this->rrttl_, ZoneFinder::NXDOMAIN,
|
||||
this->empty_rdatas_, this->empty_rdatas_);
|
||||
EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->findAll(Name("noexample.org"),
|
||||
target)->code);
|
||||
EXPECT_THROW(finder->find(Name("noexample.org"), this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
EXPECT_THROW(finder->findAll(Name("noexample.org"), target),
|
||||
OutOfZoneFind);
|
||||
|
||||
// totally unrelated domain, smaller number of labels
|
||||
doFindTest(*finder, Name("com"), this->qtype_, this->qtype_,
|
||||
this->rrttl_, ZoneFinder::NXDOMAIN,
|
||||
this->empty_rdatas_, this->empty_rdatas_);
|
||||
EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->findAll(Name("com"), target)->code);
|
||||
EXPECT_THROW(finder->find(Name("com"), this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
EXPECT_THROW(finder->findAll(Name("com"), target), OutOfZoneFind);
|
||||
|
||||
// totally unrelated domain, same number of labels
|
||||
doFindTest(*finder, Name("example.com"), this->qtype_, this->qtype_,
|
||||
this->rrttl_, ZoneFinder::NXDOMAIN,
|
||||
this->empty_rdatas_, this->empty_rdatas_);
|
||||
EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->findAll(Name("example.com"),
|
||||
target)->code);
|
||||
EXPECT_THROW(finder->find(Name("example.com"), this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
EXPECT_THROW(finder->findAll(Name("example.com"), target), OutOfZoneFind);
|
||||
|
||||
// totally unrelated domain, larger number of labels
|
||||
doFindTest(*finder, Name("more.example.com"), this->qtype_, this->qtype_,
|
||||
this->rrttl_, ZoneFinder::NXDOMAIN,
|
||||
this->empty_rdatas_, this->empty_rdatas_);
|
||||
EXPECT_EQ(ZoneFinder::NXDOMAIN, finder->findAll(Name("more.example.com"),
|
||||
target)->code);
|
||||
EXPECT_THROW(finder->find(Name("more.example.com"), this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
EXPECT_THROW(finder->findAll(Name("more.example.com"), target),
|
||||
OutOfZoneFind);
|
||||
}
|
||||
|
||||
TYPED_TEST(DatabaseClientTest, findDelegation) {
|
||||
@ -2835,10 +2833,10 @@ TYPED_TEST(DatabaseClientTest, addDeviantRR) {
|
||||
// regardless of whether adding the RR succeeded, so this check
|
||||
// actually doesn't confirm it.
|
||||
SCOPED_TRACE("add out-of-zone RR");
|
||||
doFindTest(this->updater_->getFinder(), Name("example.com"),
|
||||
this->qtype_, this->qtype_, this->rrttl_,
|
||||
ZoneFinder::NXDOMAIN, this->empty_rdatas_,
|
||||
this->empty_rdatas_);
|
||||
EXPECT_THROW(this->updater_->getFinder().find(Name("example.com"),
|
||||
this->qtype_,
|
||||
ZoneFinder::FIND_DEFAULT),
|
||||
OutOfZoneFind);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -899,8 +899,9 @@ TEST_F(InMemoryZoneFinderTest, findAny) {
|
||||
findAllTest(origin_, ZoneFinder::SUCCESS, expected_sets);
|
||||
|
||||
// out zone name
|
||||
findAllTest(Name("example.com"), ZoneFinder::NXDOMAIN,
|
||||
vector<ConstRRsetPtr>());
|
||||
EXPECT_THROW(findAllTest(Name("example.com"), ZoneFinder::NXDOMAIN,
|
||||
vector<ConstRRsetPtr>()),
|
||||
OutOfZoneFind);
|
||||
|
||||
expected_sets.clear();
|
||||
expected_sets.push_back(rr_child_glue_);
|
||||
@ -997,8 +998,8 @@ InMemoryZoneFinderTest::findCheck(ZoneFinder::FindResultFlags expected_flags) {
|
||||
// These domains don't exist (and one is out of the zone)
|
||||
findTest(Name("nothere.example.org"), RRType::A(), ZoneFinder::NXDOMAIN,
|
||||
true, ConstRRsetPtr(), expected_flags);
|
||||
findTest(Name("example.net"), RRType::A(), ZoneFinder::NXDOMAIN, true,
|
||||
ConstRRsetPtr(), expected_flags);
|
||||
EXPECT_THROW(zone_finder_.find(Name("example.net"), RRType::A(),
|
||||
ZoneFinder::FIND_DEFAULT), OutOfZoneFind);
|
||||
}
|
||||
|
||||
TEST_F(InMemoryZoneFinderTest, find) {
|
||||
@ -1053,8 +1054,9 @@ InMemoryZoneFinderTest::emptyNodeCheck(
|
||||
// Note: basically we don't expect such a query to be performed (the common
|
||||
// operation is to identify the best matching zone first then perform
|
||||
// search it), but we shouldn't be confused even in the unexpected case.
|
||||
findTest(Name("org"), RRType::A(), ZoneFinder::NXDOMAIN, true,
|
||||
ConstRRsetPtr(), expected_flags);
|
||||
EXPECT_THROW(zone_finder_.find(Name("org"), RRType::A(),
|
||||
ZoneFinder::FIND_DEFAULT),
|
||||
OutOfZoneFind);
|
||||
}
|
||||
|
||||
TEST_F(InMemoryZoneFinderTest, emptyNode) {
|
||||
@ -1512,14 +1514,16 @@ TEST_F(InMemoryZoneFinderTest, swap) {
|
||||
EXPECT_EQ(RRClass::CH(), finder1.getClass());
|
||||
EXPECT_EQ(RRClass::IN(), finder2.getClass());
|
||||
// make sure the zone data is swapped, too
|
||||
findTest(origin_, RRType::NS(), ZoneFinder::NXDOMAIN, false,
|
||||
ConstRRsetPtr(), ZoneFinder::RESULT_DEFAULT, &finder1);
|
||||
EXPECT_THROW(finder1.find(origin_, RRType::NS(),
|
||||
ZoneFinder::FIND_DEFAULT),
|
||||
OutOfZoneFind);
|
||||
findTest(other_origin, RRType::TXT(), ZoneFinder::SUCCESS, false,
|
||||
ConstRRsetPtr(), ZoneFinder::RESULT_DEFAULT, &finder1);
|
||||
findTest(origin_, RRType::NS(), ZoneFinder::SUCCESS, false,
|
||||
ConstRRsetPtr(), ZoneFinder::RESULT_DEFAULT, &finder2);
|
||||
findTest(other_origin, RRType::TXT(), ZoneFinder::NXDOMAIN, false,
|
||||
ConstRRsetPtr(), ZoneFinder::RESULT_DEFAULT, &finder2);
|
||||
EXPECT_THROW(finder2.find(other_origin, RRType::TXT(),
|
||||
ZoneFinder::FIND_DEFAULT),
|
||||
OutOfZoneFind);
|
||||
}
|
||||
|
||||
TEST_F(InMemoryZoneFinderTest, getFileName) {
|
||||
|
@ -27,6 +27,14 @@
|
||||
namespace isc {
|
||||
namespace datasrc {
|
||||
|
||||
/// \brief Thrown when ZoneFinder::find() is called for out-of-zone data
|
||||
///
|
||||
class OutOfZoneFind : public Exception {
|
||||
public:
|
||||
OutOfZoneFind(const char* file, size_t line, const char* what) :
|
||||
isc::Exception(file, line, what) {}
|
||||
};
|
||||
|
||||
/// \brief The base class to search a zone for RRsets
|
||||
///
|
||||
/// The \c ZoneFinder class is an abstract base class for representing
|
||||
@ -466,6 +474,8 @@ public:
|
||||
///
|
||||
/// \exception std::bad_alloc Memory allocation such as for constructing
|
||||
/// the resulting RRset fails
|
||||
/// \throw OutOfZoneFind The Name \c name is outside of the origin
|
||||
/// of the zone of this ZoneFinder.
|
||||
/// \exception DataSourceError Derived class specific exception, e.g.
|
||||
/// when encountering a bad zone configuration or database connection
|
||||
/// failure. Although these are considered rare, exceptional events,
|
||||
|
@ -233,6 +233,7 @@ initModulePart_ZoneJournalReader(PyObject* mod) {
|
||||
}
|
||||
|
||||
PyObject* po_DataSourceError;
|
||||
PyObject* po_OutOfZoneFind;
|
||||
PyObject* po_NotImplemented;
|
||||
|
||||
PyModuleDef iscDataSrc = {
|
||||
@ -287,6 +288,9 @@ PyInit_datasrc(void) {
|
||||
po_DataSourceError = PyErr_NewException("isc.datasrc.Error", NULL,
|
||||
NULL);
|
||||
PyObjectContainer(po_DataSourceError).installToModule(mod, "Error");
|
||||
po_OutOfZoneFind = PyErr_NewException("isc.datasrc.OutOfZoneFind",
|
||||
NULL, NULL);
|
||||
PyObjectContainer(po_OutOfZoneFind).installToModule(mod, "OutOfZoneFind");
|
||||
po_NotImplemented = PyErr_NewException("isc.datasrc.NotImplemented",
|
||||
NULL, NULL);
|
||||
PyObjectContainer(po_NotImplemented).installToModule(mod,
|
||||
|
@ -97,6 +97,10 @@ PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) {
|
||||
} else {
|
||||
return (Py_BuildValue("IOI", r, Py_None, result_flags));
|
||||
}
|
||||
} catch (const OutOfZoneFind& oozf) {
|
||||
PyErr_SetString(getDataSourceException("OutOfZoneFind"),
|
||||
oozf.what());
|
||||
return (NULL);
|
||||
} catch (const DataSourceError& dse) {
|
||||
PyErr_SetString(getDataSourceException("Error"), dse.what());
|
||||
return (NULL);
|
||||
|
@ -379,11 +379,10 @@ class DataSrcClient(unittest.TestCase):
|
||||
self.assertEqual(finder.NXDOMAIN, result)
|
||||
self.assertEqual(None, rrset)
|
||||
|
||||
result, rrset, _ = finder.find(isc.dns.Name("www.some.other.domain"),
|
||||
isc.dns.RRType.A(),
|
||||
finder.FIND_DEFAULT)
|
||||
self.assertEqual(finder.NXDOMAIN, result)
|
||||
self.assertEqual(None, rrset)
|
||||
|
||||
self.assertRaises(isc.datasrc.OutOfZoneFind, finder.find,
|
||||
isc.dns.Name("www.some.other.domain"),
|
||||
isc.dns.RRType.A(), finder.FIND_DEFAULT)
|
||||
|
||||
result, rrset, _ = finder.find(isc.dns.Name("www.example.com"),
|
||||
isc.dns.RRType.TXT(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user