Commit 3336f575 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

Merge branch 'work/log/datasrc'

parents f15bdf84 25c5c370
......@@ -7,7 +7,7 @@ AM_CPPFLAGS += $(SQLITE_CFLAGS)
AM_CXXFLAGS = $(B10_CXXFLAGS)
CLEANFILES = *.gcno *.gcda
CLEANFILES = *.gcno *.gcda messagedef.h messagedef.cc
lib_LTLIBRARIES = libdatasrc.la
libdatasrc_la_SOURCES = data_source.h data_source.cc
......@@ -20,3 +20,16 @@ libdatasrc_la_SOURCES += zonetable.h zonetable.cc
libdatasrc_la_SOURCES += memory_datasrc.h memory_datasrc.cc
libdatasrc_la_SOURCES += zone.h
libdatasrc_la_SOURCES += result.h
libdatasrc_la_SOURCES += logger.h logger.cc
nodist_libdatasrc_la_SOURCES = messagedef.h messagedef.cc
libdatasrc_la_LIBADD = $(top_builddir)/src/lib/exceptions/libexceptions.la
libdatasrc_la_LIBADD += $(top_builddir)/src/lib/dns/libdns++.la
libdatasrc_la_LIBADD += $(top_builddir)/src/lib/log/liblog.la
libdatasrc_la_LIBADD += $(top_builddir)/src/lib/cc/libcc.la
BUILT_SOURCES = messagedef.h messagedef.cc
messagedef.h messagedef.cc: Makefile messagedef.mes
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/datasrc/messagedef.mes
EXTRA_DIST = messagedef.mes
......@@ -24,6 +24,7 @@
#include <list>
#include <datasrc/cache.h>
#include <datasrc/logger.h>
using namespace std;
using namespace isc::dns;
......@@ -204,16 +205,21 @@ public:
// HotCacheImpl constructor
HotCacheImpl::HotCacheImpl(int slots, bool enabled) :
enabled_(enabled), slots_(slots), count_(0)
{}
{
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_CACHE_CREATE);
}
// Insert a cache node into the cache
inline void
HotCacheImpl::insert(const CacheNodePtr node) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_INSERT).
arg(node->getRRset()->getName());
std::map<Question, CacheNodePtr>::const_iterator iter;
iter = map_.find(node->question);
if (iter != map_.end()) {
CacheNodePtr old = iter->second;
if (old && old->isValid()) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_OLD_FOUND);
remove(old);
}
}
......@@ -225,6 +231,7 @@ HotCacheImpl::insert(const CacheNodePtr node) {
++count_;
if (slots_ != 0 && count_ > slots_) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_FULL);
remove(lru_.back());
}
}
......@@ -245,6 +252,8 @@ HotCacheImpl::promote(CacheNodePtr node) {
// Remove a node from the LRU list and the map
void
HotCacheImpl::remove(ConstCacheNodePtr node) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_REMOVE).
arg(node->getRRset()->getName());
lru_.erase(node->lru_entry_);
map_.erase(node->question);
--count_;
......@@ -257,6 +266,7 @@ HotCache::HotCache(const int slots) {
// HotCache destructor
HotCache::~HotCache() {
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_CACHE_DESTROY);
delete impl_;
}
......@@ -303,18 +313,21 @@ HotCache::retrieve(const Name& n, const RRClass& c, const RRType& t,
std::map<Question, CacheNodePtr>::const_iterator iter;
iter = impl_->map_.find(Question(n, c, t));
if (iter == impl_->map_.end()) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_NOT_FOUND).arg(n);
return (false);
}
CacheNodePtr node = iter->second;
if (node->isValid()) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_FOUND).arg(n);
impl_->promote(node);
rrset = node->getRRset();
flags = node->getFlags();
return (true);
}
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_CACHE_EXPIRED).arg(n);
impl_->remove(node);
return (false);
}
......@@ -328,6 +341,9 @@ HotCache::setSlots(const int slots) {
return;
}
logger.info(DATASRC_CACHE_SLOTS).arg(slots).arg(max(0, impl_->count_ -
slots));
while (impl_->slots_ != 0 && impl_->count_ > impl_->slots_) {
impl_->remove(impl_->lru_.back());
}
......@@ -343,6 +359,11 @@ HotCache::getSlots() const {
void
HotCache::setEnabled(const bool e) {
impl_->enabled_ = e;
if (e) {
logger.info(DATASRC_CACHE_ENABLE);
} else {
logger.info(DATASRC_CACHE_DISABLE);
}
}
/// Indicate whether the cache is enabled
......
......@@ -25,6 +25,7 @@
#include <datasrc/cache.h>
#include <datasrc/data_source.h>
#include <datasrc/query.h>
#include <datasrc/logger.h>
#include <util/encode/base32hex.h>
#include <util/hash/sha1.h>
......@@ -83,7 +84,7 @@ class ZoneInfo {
public:
ZoneInfo(DataSrc* ts,
const isc::dns::Name& n,
const isc::dns::RRClass& c,
const isc::dns::RRClass& c,
const isc::dns::RRType& t = isc::dns::RRType::ANY()) :
top_source_(ts),
dsm_(((t == RRType::DS() && n.getLabelCount() != 1)
......@@ -123,6 +124,8 @@ getAdditional(Query& q, ConstRRsetPtr rrset) {
const Rdata& rd(it->getCurrent());
if (rrset->getType() == RRType::NS()) {
const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_GET_NS_ADDITIONAL).
arg(ns.getNSName()).arg(rrset->getName());
q.tasks().push(QueryTaskPtr(
new QueryTask(q, ns.getNSName(),
Message::SECTION_ADDITIONAL,
......@@ -130,6 +133,8 @@ getAdditional(Query& q, ConstRRsetPtr rrset) {
QueryTask::GETADDITIONAL)));
} else if (rrset->getType() == RRType::MX()) {
const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_GET_MX_ADDITIONAL).
arg(mx.getMXName()).arg(rrset->getName());
q.tasks().push(QueryTaskPtr(
new QueryTask(q, mx.getMXName(),
Message::SECTION_ADDITIONAL,
......@@ -143,11 +148,14 @@ getAdditional(Query& q, ConstRRsetPtr rrset) {
// understand DNAME
void
synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_SYNTH_CNAME).
arg(rrset->getName());
RdataIteratorPtr it = rrset->getRdataIterator();
// More than one DNAME RR in the RRset is illegal, so we only have
// to process the first one.
if (it->isLast()) {
logger.error(DATASRC_QUERY_EMPTY_DNAME).arg(rrset->getName());
return;
}
......@@ -171,16 +179,20 @@ synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
// to by a CNAME record
void
chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_FOLLOW_CNAME).
arg(rrset->getName());
RdataIteratorPtr it = rrset->getRdataIterator();
// More than one CNAME RR in the RRset is illegal, so we only have
// to process the first one.
if (it->isLast()) {
logger.error(DATASRC_QUERY_EMPTY_CNAME).arg(rrset->getName());
return;
}
// Stop chasing CNAMES after 16 lookups, to prevent loops
if (q.tooMany()) {
logger.error(DATASRC_QUERY_TOO_MANY_CNAMES).arg(rrset->getName());
return;
}
......@@ -194,6 +206,8 @@ chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
// Check the cache for data which can answer the current query task.
bool
checkCache(QueryTask& task, RRsetList& target) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_CHECK_CACHE).
arg(task.qname).arg(task.qtype);
HotCache& cache = task.q.getCache();
RRsetList rrsets;
RRsetPtr rrset;
......@@ -206,6 +220,9 @@ checkCache(QueryTask& task, RRsetList& target) {
// ANY queries must be handled by the low-level data source,
// or the results won't be guaranteed to be complete
if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
LOG_DEBUG(logger, DBG_TRACE_DATA,
DATASRC_QUERY_NO_CACHE_ANY_SIMPLE).arg(task.qname).
arg(task.qtype).arg(task.qclass);
break;
}
......@@ -235,6 +252,8 @@ checkCache(QueryTask& task, RRsetList& target) {
case QueryTask::AUTH_QUERY: // Find exact RRset or CNAME
if (task.qtype == RRType::ANY() || task.qclass == RRClass::ANY()) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_NO_CACHE_ANY_AUTH).
arg(task.qname).arg(task.qtype).arg(task.qclass);
break;
}
......@@ -353,6 +372,8 @@ DataSrc::Result
doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
HotCache& cache = task.q.getCache();
RRsetPtr rrset;
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_DO_QUERY).arg(task.qname).
arg(task.qtype);
// First off, make sure at least we have a matching zone in some data
// source. We must do this before checking the cache, because it can
......@@ -363,11 +384,14 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
const Name* const zonename = zoneinfo.getEnclosingZone();
if (ds == NULL) {
task.flags |= DataSrc::NO_SUCH_ZONE;
logger.info(DATASRC_QUERY_NO_ZONE).arg(task.qname).arg(task.qclass);
return (DataSrc::SUCCESS);
}
// Then check the cache for matching data
if (checkCache(task, target)) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_CACHED).
arg(task.qname).arg(task.qtype);
return (DataSrc::SUCCESS);
}
......@@ -378,10 +402,13 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
DataSrc::Result result;
switch (task.op) {
case QueryTask::SIMPLE_QUERY:
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_SIMPLE).
arg(task.qname).arg(task.qtype);
result = ds->findExactRRset(task.qname, task.qclass, task.qtype,
target, task.flags, zonename);
if (result != DataSrc::SUCCESS) {
logger.error(DATASRC_QUERY_SIMPLE_FAIL).arg(result);
return (result);
}
......@@ -403,10 +430,13 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
return (result);
case QueryTask::AUTH_QUERY:
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_AUTH).
arg(task.qname).arg(task.qtype);
result = ds->findRRset(task.qname, task.qclass, task.qtype,
target, task.flags, zonename);
if (result != DataSrc::SUCCESS) {
logger.error(DATASRC_QUERY_AUTH_FAIL).arg(result);
return (result);
}
......@@ -439,10 +469,16 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
case QueryTask::GLUE_QUERY:
case QueryTask::NOGLUE_QUERY:
LOG_DEBUG(logger, DBG_TRACE_DATA, task.op == QueryTask::GLUE_QUERY ?
DATASRC_QUERY_IS_GLUE : DATASRC_QUERY_IS_NOGLUE).
arg(task.qname).arg(task.qtype);
result = ds->findAddrs(task.qname, task.qclass, target,
task.flags, zonename);
if (result != DataSrc::SUCCESS) {
logger.error(task.op == QueryTask::GLUE_QUERY ?
DATASRC_QUERY_GLUE_FAIL : DATASRC_QUERY_NOGLUE_FAIL).
arg(result);
return (result);
}
......@@ -468,10 +504,13 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
return (result);
case QueryTask::REF_QUERY:
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_IS_REF).
arg(task.qname).arg(task.qtype);
result = ds->findReferral(task.qname, task.qclass, target,
task.flags, zonename);
if (result != DataSrc::SUCCESS) {
logger.error(DATASRC_QUERY_REF_FAIL).arg(result);
return (result);
}
......@@ -505,6 +544,7 @@ doQueryTask(QueryTask& task, ZoneInfo& zoneinfo, RRsetList& target) {
}
// Not reached
logger.error(DATASRC_QUERY_INVALID_OP);
return (DataSrc::ERROR);
}
......@@ -516,6 +556,8 @@ inline void
addToMessage(Query& q, const Message::Section sect, RRsetPtr rrset,
bool no_dnssec = false)
{
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_RRSET).
arg(rrset->getName()).arg(rrset->getType());
Message& m = q.message();
if (no_dnssec) {
if (rrset->getType() == RRType::RRSIG() ||
......@@ -534,6 +576,7 @@ addToMessage(Query& q, const Message::Section sect, RRsetPtr rrset,
// Copy referral information into the authority section of a message
inline void
copyAuth(Query& q, RRsetList& auth) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_COPY_AUTH);
BOOST_FOREACH(RRsetPtr rrset, auth) {
if (rrset->getType() == RRType::DNAME()) {
continue;
......@@ -571,6 +614,9 @@ refQuery(const Query& q, const Name& name, ZoneInfo& zoneinfo,
// they'll be handled in a normal lookup in the zone.
inline bool
hasDelegation(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_DELEGATION).
arg(task->qname);
const Name* const zonename = zoneinfo.getEnclosingZone();
if (zonename == NULL) {
if (task->state == QueryTask::GETANSWER) {
......@@ -636,6 +682,7 @@ addSOA(Query& q, ZoneInfo& zoneinfo) {
RRsetList soa;
const Name* const zonename = zoneinfo.getEnclosingZone();
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_SOA).arg(*zonename);
QueryTask newtask(q, *zonename, RRType::SOA(), QueryTask::SIMPLE_QUERY);
RETERR(doQueryTask(newtask, zoneinfo, soa));
if (newtask.flags != 0) {
......@@ -649,6 +696,7 @@ addSOA(Query& q, ZoneInfo& zoneinfo) {
inline DataSrc::Result
addNSEC(Query& q, const Name& name, ZoneInfo& zoneinfo) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_NSEC).arg(name);
RRsetList nsec;
QueryTask newtask(q, name, RRType::NSEC(), QueryTask::SIMPLE_QUERY);
......@@ -665,9 +713,11 @@ inline DataSrc::Result
getNsec3(Query& q, ZoneInfo& zoneinfo, string& hash, RRsetPtr& target) {
const DataSrc* ds = zoneinfo.getDataSource();
const Name* const zonename = zoneinfo.getEnclosingZone();
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_ADD_NSEC3).arg(*zonename);
if (ds == NULL) {
q.message().setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_NO_DS_NSEC3).arg(*zonename);
return (DataSrc::ERROR);
}
......@@ -770,6 +820,7 @@ proveNX(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, const bool wildcard) {
const DataSrc* ds = zoneinfo.getDataSource();
if (ds == NULL) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_NO_DS_NSEC).arg(*zonename);
return (DataSrc::ERROR);
}
ds->findPreviousName(task->qname, nsecname, zonename);
......@@ -798,6 +849,7 @@ proveNX(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, const bool wildcard) {
// Attempt a wildcard lookup
inline DataSrc::Result
tryWildcard(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, bool& found) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_QUERY_WILDCARD).arg(task->qname);
Message& m = q.message();
DataSrc::Result result;
found = false;
......@@ -851,6 +903,8 @@ tryWildcard(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, bool& found) {
result = proveNX(q, task, zoneinfo, true);
if (result != DataSrc::SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_WILDCARD_PROVENX_FAIL).
arg(task->qname).arg(result);
return (DataSrc::ERROR);
}
}
......@@ -873,6 +927,8 @@ tryWildcard(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, bool& found) {
RRsetList auth;
if (!refQuery(q, *zonename, zoneinfo, auth)) {
logger.error(DATASRC_QUERY_WILDCARD_REFERRAL).arg(task->qname).
arg(result);
return (DataSrc::ERROR);
}
......@@ -888,6 +944,8 @@ tryWildcard(Query& q, QueryTaskPtr task, ZoneInfo& zoneinfo, bool& found) {
//
void
DataSrc::doQuery(Query& q) {
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_QUERY_PROCESS).arg(q.qname()).
arg(q.qclass());
Message& m = q.message();
vector<RRsetPtr> additional;
......@@ -905,6 +963,7 @@ DataSrc::doQuery(Query& q) {
// Can't query directly for RRSIG.
if (task->qtype == RRType::RRSIG()) {
m.setRcode(Rcode::REFUSED());
logger.warn(DATASRC_QUERY_RRSIG).arg(task->qname);
return;
}
......@@ -912,6 +971,7 @@ DataSrc::doQuery(Query& q) {
if (task->op == QueryTask::SIMPLE_QUERY ||
task->op == QueryTask::REF_QUERY) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_MISPLACED_TASK);
return;
}
......@@ -931,6 +991,7 @@ DataSrc::doQuery(Query& q) {
result = doQueryTask(*task, zoneinfo, data);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_TASK_FAIL).arg(result);
return;
}
......@@ -940,6 +1001,7 @@ DataSrc::doQuery(Query& q) {
if (task->flags == NO_SUCH_ZONE) {
if (task->state == QueryTask::GETANSWER) {
m.setRcode(Rcode::REFUSED());
// No need to log it here, it was already logged in doQueryTask
return;
}
continue;
......@@ -981,6 +1043,7 @@ DataSrc::doQuery(Query& q) {
RRsetList auth;
if (!refQuery(q, Name(*zonename), zoneinfo, auth) ||
!findRRsetFromList(auth, RRType::NS())) {
logger.error(DATASRC_QUERY_MISSING_NS).arg(*zonename);
isc_throw(DataSourceError,
"NS RR not found in " << *zonename << "/" <<
q.qclass());
......@@ -1005,10 +1068,12 @@ DataSrc::doQuery(Query& q) {
continue;
default:
logger.error(DATASRC_UNEXPECTED_QUERY_STATE);
isc_throw (Unexpected, "unexpected query state");
}
} else if (result == ERROR || result == NOT_IMPLEMENTED) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_FAIL);
return;
} else if ((task->flags & CNAME_FOUND) != 0) {
// The qname node contains a CNAME. Add a new task to the
......@@ -1026,6 +1091,7 @@ DataSrc::doQuery(Query& q) {
m.setHeaderFlag(Message::HEADERFLAG_AA, false);
if (!refQuery(q, task->qname, zoneinfo, auth)) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_BAD_REFERRAL).arg(task->qname);
return;
}
BOOST_FOREACH (RRsetPtr rrset, auth) {
......@@ -1057,6 +1123,7 @@ DataSrc::doQuery(Query& q) {
result = tryWildcard(q, task, zoneinfo, wildcard_found);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_WILDCARD_FAIL).arg(task->qname);
return;
}
......@@ -1078,6 +1145,7 @@ DataSrc::doQuery(Query& q) {
result = addSOA(q, zoneinfo);
if (result != SUCCESS) {
logger.error(DATASRC_QUERY_MISSING_SOA).arg(*zonename);
isc_throw(DataSourceError,
"SOA RR not found in " << *zonename <<
"/" << q.qclass());
......@@ -1094,6 +1162,7 @@ DataSrc::doQuery(Query& q) {
result = proveNX(q, task, zoneinfo, false);
if (result != DataSrc::SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_PROVENX_FAIL).arg(task->qname);
return;
}
}
......@@ -1102,6 +1171,7 @@ DataSrc::doQuery(Query& q) {
} else {
// Should never be reached!
m.setRcode(Rcode::SERVFAIL());
logger.error(DATASRC_QUERY_UNKNOWN_RESULT);
return;
}
}
......@@ -1197,7 +1267,10 @@ DataSrc::findReferral(const Name& qname, const RRClass& qclass,
void
MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src) {
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_META_ADD);
if (getClass() != RRClass::ANY() && data_src->getClass() != getClass()) {
logger.error(DATASRC_META_ADD_CLASS_MISMATCH).
arg(data_src->getClass()).arg(getClass());
isc_throw(Unexpected, "class mismatch");
}
......@@ -1206,6 +1279,7 @@ MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src) {
void
MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src) {
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_META_REMOVE);
std::vector<ConstDataSrcPtr>::iterator it, itr;
for (it = data_sources.begin(); it != data_sources.end(); ++it) {
if (*it == data_src) {
......
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <datasrc/logger.h>
namespace isc {
namespace datasrc {
isc::log::Logger logger("datasrc");
}
}
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef __DATASRC_LOGGER_H
#define __DATASRC_LOGGER_H
#include <log/macros.h>
#include <datasrc/messagedef.h>
/// \file logger.h
/// \brief Data Source library global logger
///
/// This holds the logger for the data source library. It is a private header
/// and should not be included in any publicly used header, only in local
/// cc files.
namespace isc {
namespace datasrc {
/// \brief The logger for this library
extern isc::log::Logger logger;
enum {
/// \brief Trace basic operations
DBG_TRACE_BASIC = 10,
/// \brief Trace data changes and lookups as well
DBG_TRACE_DATA = 20,
/// \brief Detailed even about how the lookups happen
DBG_TRACE_DETAILED = 50
};
}
}
#endif
......@@ -24,6 +24,7 @@
#include <datasrc/memory_datasrc.h>
#include <datasrc/rbtree.h>
#include <datasrc/logger.h>
using namespace std;
using namespace isc::dns;
......@@ -94,6 +95,8 @@ struct MemoryZone::MemoryZoneImpl {
l > origin_labels;
--l, wname = wname.split(1)) {
if (wname.isWildcard()) {
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ADD_WILDCARD).
arg(name);
// Ensure a separate level exists for the "wildcarding" name,
// and mark the node as "wild".
DomainNode* node;
......@@ -130,10 +133,13 @@ struct MemoryZone::MemoryZoneImpl {
// (depending on how we support DNSSEC). We should revisit it
// at that point.
if (!domain->empty()) {
LOG_ERROR(logger, DATASRC_MEM_CNAME_TO_NONEMPTY).
arg(rrset->getName());
isc_throw(AddError, "CNAME can't be added with other data for "
<< rrset->getName());
}
} else if (domain->find(RRType::CNAME()) != domain->end()) {
LOG_ERROR(logger, DATASRC_MEM_CNAME_COEXIST).arg(rrset->getName());
isc_throw(AddError, "CNAME and " << rrset->getType() <<
" can't coexist for " << rrset->getName());
}
......@@ -151,6 +157,7 @@ struct MemoryZone::MemoryZoneImpl {
(rrset->getType() == RRType::NS() &&
domain->find(RRType::DNAME()) != domain->end())))
{
LOG_ERROR(logger, DATASRC_MEM_DNAME_NS).arg(rrset->getName());
isc_throw(AddError, "DNAME can't coexist with NS in non-apex "
"domain " << rrset->getName());
}
......@@ -172,6 +179,8 @@ struct MemoryZone::MemoryZoneImpl {
// XXX: this is not only for CNAME or DNAME. We should generalize
// this code for all other "singleton RR types" (such as SOA) in a
// separate task.
LOG_ERROR(logger, DATASRC_MEM_SINGLETON).arg(rrset->getName()).
arg(rrset->getType());
isc_throw(AddError, "multiple RRs of singleton type for "
<< rrset->getName());
}
......@@ -180,6 +189,8 @@ struct MemoryZone::MemoryZoneImpl {
if (compare.getRelation() != NameComparisonResult::SUPERDOMAIN &&