Commit b4aed028 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[trac534] Returning DNAME

parent f0a09daf
......@@ -194,31 +194,48 @@ struct MemoryZone::MemoryZoneImpl {
/// It will be passed to \c zonecutCallback() and record a possible
/// zone cut node and related RRset (normally NS or DNAME).
struct FindState {
FindState(FindOptions options) : zonecut_node_(NULL),
FindState(FindOptions options) :
const DomainNode* zonecut_node_;
const DomainNode* dname_node_;
ConstRRsetPtr rrset_;
const FindOptions options_;
// A callback called from possible zone cut nodes. This will be passed
// from the \c find() method to \c RBTree::find().
static bool zonecutCallback(const DomainNode& node, FindState* state) {
// A callback called from possible zone cut nodes and nodes with DNAME.
// This will be passed from the \c find() method to \c RBTree::find().
static bool cutCallback(const DomainNode& node, FindState* state) {
// We perform callback check only for the highest zone cut in the
// rare case of nested zone cuts.
if (state->zonecut_node_ != NULL) {
return (false);
const Domain::const_iterator found(node.getData()->find(RRType::NS()));
if (found != node.getData()->end()) {
// We need to look for DNAME first, there's allowed case where
// DNAME and NS coexist in the apex. DNAME is the one to notice,
// the NS is authoritative, not delegation
const Domain::const_iterator foundDNAME(node.getData()->find(
if (foundDNAME != node.getData()->end()) {
state->dname_node_ = &node;
state->rrset_ = foundDNAME->second;
// No more processing below the DNAME
return true;
// Look for NS
const Domain::const_iterator foundNS(node.getData()->find(
if (foundNS != node.getData()->end()) {
// BIND 9 checks if this node is not the origin. But it cannot
// be the origin because we don't enable the callback at the
// origin node (see MemoryZoneImpl::add()). Or should we do a
// double check for it?
state->zonecut_node_ = &node;
state->rrset_ = found->second;
state->rrset_ = foundNS->second;
// Unless glue is allowed the search stops here, so we return
// false; otherwise return true to continue the search.
......@@ -242,8 +259,13 @@ struct MemoryZone::MemoryZoneImpl {
// Get the node
DomainNode* node(NULL);
FindState state(options);
switch (domains_.find(name, &node, zonecutCallback, &state)) {
switch (domains_.find(name, &node, cutCallback, &state)) {
case DomainTree::PARTIALMATCH:
if (state.dname_node_ != NULL) {
// We were traversing a DNAME node (and wanted to go
// lower below it), so return the DNAME
return (FindResult(DNAME, state.rrset_));
if (state.zonecut_node_ != NULL) {
return (FindResult(DELEGATION, state.rrset_));
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment