Commit ceeb87f6 authored by Xie Jiagui's avatar Xie Jiagui
Browse files

Merge branch 'master' into trac1462

parents 0fa94211 707480d9
358. [bug] jinmei
b10-resolver ignored default configuration parameters if listen_on
failed (this can easily happen especially for a test environment
where the run time user doesn't have root privilege), and even if
listen_on was updated later the resolver wouldn't work correctly
unless it's fully restarted (for example, all queries would be
rejected due to an empty ACL).
(Trac #1424, git 2cba8cb83cde4f34842898a848c0b1182bc20597)
357. [bug] jinmei
ZoneFinder::find() for database based data sources didn't
correctly identify out-of-zone query name and could return a
confusing result such as NXRRSET. It now returns NXDOMAIN with an
empty RRset. Note: we should rather throw an exception in such a
case, which should be revisited later (see Trac #1536).
(Trac #1430, git b35797ba1a49c78246abc8f2387901f9690b328d)
356. [doc] tomek
BIND10 Guide updated. It now describes DHCPv4 and DHCPv6
components, including their overview, usage, supported standard
and limitations. libdhcp++ is also described.
(Trac #1367, git 3758ab360efe1cdf616636b76f2e0fb41f2a62a0)
355. [bug] jinmei
Python xfrin.diff module incorrectly combined RRSIGs of different
type covered, possibly merging different TTLs. As a result a
secondary server could store different RRSIGs than those at the
primary server if it gets these records via IXFR.
(Trac #1502, git 57b06f8cb6681f591fa63f25a053eb6f422896ef)
354. [func] tomek
dhcp4: Support for DISCOVER and OFFER implemented. b10-dhcp4 is
now able to offer hardcoded leases to DHCPv4 clients.
dhcp6: Code refactored to use the same approach as dhcp4.
(Trac #1230, git aac05f566c49daad4d3de35550cfaff31c124513)
353. [func] tomek
libdhcp++: Interface detection in Linux implemented. libdhcp++
is now able (on Linux systems) to detect available network
interfaces, its link-layer addresses, flags and configured
IPv4 and IPv6 addresses. Interface detection on other
systems is planned.
(Trac #1237, git 8a040737426aece7cc92a795f2b712d7c3407513)
352. [func] tomek
libdhcp++: Transmission and reception of DHCPv4 packets is now
implemented. Low-level hacks are not implemented for transmission
to hosts that don't have IPv4 address yet, so currently the code
is usable for communication with relays only, not hosts on the
same link.
(Trac #1239, #1240, git f382050248b5b7ed1881b086d89be2d9dd8fe385)
351. [func] fdupont
Alpha version of DHCP benchmarking tool added. "perfdhcp" is able to
test both IPv4 and IPv6 servers: it can time the four-packet exchange
(DORA and SARR) as well as time the initial two-packet exchange (DO
and SA). More information can be obtained by invoking the utility
(in tests/tools/perfdhcp) with the "-h" flag.
(Trac #1450, git 85083a76107ba2236732b45524ce7018eefbaf90)
350. [func]* vorner
The target parameter of ZoneFinder::find is no longer present, as the
interface was awkward. To get all the RRsets of a single domain, use
the new findAll method (the same applies to python version, the method
is named find_all).
(Trac #1483,#1484, git 0020456f8d118c9f3fd6fc585757c822b79a96f6)
349. [bug] dvv
resolver: If an upstream server responds with FORMERR to an EDNS
query, try querying it without EDNS.
(Trac #1386, git 99ad0292af284a246fff20b3702fbd7902c45418)
348. [bug] stephen
By default the logging output stream is now flushed after each write.
This fixes a problem seen on some systems where the log output from
different processes was jumbled up. Flushing can be disabled by
setting the appropriate option in the logging configuration.
(Trac #1405, git 2f0aa20b44604b671e6bde78815db39381e563bf)
347. [bug] jelte
Fixed a bug where adding Zonemgr/secondary_zones without explicitely
setting the class value of the added zone resulted in a cryptic
error in bindctl ("Error: class"). It will now correctly default to
IN if not set. This also adds better checks on the name and class
values, and better errors if they are bad.
(Trac #1414, git 7b122af8489acf0f28f935a19eca2c5509a3677f)
346. [build]* jreed
Renamed libdhcp to libdhcp++.
(Trac #1446, git d394e64f4c44f16027b1e62b4ac34e054b49221d)
......
......@@ -120,7 +120,7 @@ AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
AC_SUBST(SET_ENV_LIBRARY_PATH)
AC_SUBST(ENV_LIBRARY_PATH)
m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1])
m4_define([_AM_PYTHON_INTERPRETER_LIST], [python python3 python3.1 python3.2])
AC_ARG_WITH([pythonpath],
AC_HELP_STRING([--with-pythonpath=PATH],
[specify an absolute path to python executable when automatic version check (incorrectly) fails]),
......@@ -369,6 +369,36 @@ AC_HEADER_STDBOOL
AC_TYPE_SIZE_T
# Detect OS type (it may be used to do OS-specific things, e.g.
# interface detection in DHCP)
AC_MSG_CHECKING(OS family)
system=`uname -s`
case $system in
Linux)
OS_TYPE="Linux"
CPPFLAGS="$CPPFLAGS -DOS_LINUX"
;;
Darwin | FreeBSD | NetBSD | OpenBSD)
OS_TYPE="BSD"
CPPFLAGS="$CPPFLAGS -DOS_BSD"
;;
Solaris)
OS_TYPE="Solaris"
CPPFLAGS="$CPPFLAGS -DOS_SOLARIS"
;;
*)
OS_TYPE="Unknown"
AC_MSG_WARN("Unsupported OS: uname returned $system")
;;
esac
AC_MSG_RESULT($OS_TYPE)
AM_CONDITIONAL(OS_LINUX, test $OS_TYPE = Linux)
AM_COND_IF([OS_LINUX], [AC_DEFINE([OS_LINUX], [1], [Running on Linux?])])
AM_CONDITIONAL(OS_BSD, test $OS_TYPE = BSD)
AM_COND_IF([OS_BSD], [AC_DEFINE([OS_BSD], [1], [Running on BSD?])])
AM_CONDITIONAL(OS_SOLARIS, test $OS_TYPE = Solaris)
AM_COND_IF([OS_SOLARIS], [AC_DEFINE([OS_SOLARIS], [1], [Running on Solaris?])])
AC_MSG_CHECKING(for sa_len in struct sockaddr)
AC_TRY_COMPILE([
......@@ -443,7 +473,7 @@ AC_SUBST(USE_LCOV)
botan_path="yes"
AC_ARG_WITH([botan],
AC_HELP_STRING([--with-botan=PATH],
[specify exact directory of Botan library]),
[specify the path to botan-config (PATH/bin/botan-config will be used)]),
[botan_path="$withval"])
if test "${botan_path}" = "no" ; then
AC_MSG_ERROR([Need botan for libcryptolink])
......@@ -831,6 +861,20 @@ EV_SET(NULL, 0, 0, 0, 0, 0, udata);],
])
fi
# perfdhcp: If the clock_gettime() function does not exist on the system,
# use an alternative supplied in the code based on gettimeofday().
CLOCK_GETTIME_LDFLAGS=
AC_CHECK_LIB([rt], [clock_gettime], [CLOCK_GETTIME_LDFLAGS=-lrt], [])
AC_SUBST([CLOCK_GETTIME_LDFLAGS])
# perfdhcp: if getifaddrs() does not exist, have the code output a message
# that it can't be run on this version of the operating system. For the
# systems on which BIND 10 is built, this means Solaris 10. (Replacements
# for this function are long and involved, and the function is reported present
# on Solaris 11 and later, either in the libsocket or libnsl libraries.)
AC_SEARCH_LIBS([getifaddrs], [socket nsl],
[AC_DEFINE([HAVE_GETIFADDRS], [1], [getifaddrs() present])])
# /dev/poll issue: ASIO uses /dev/poll by default if it's available (generally
# the case with Solaris). Unfortunately its /dev/poll specific code would
# trigger the gcc's "missing-field-initializers" warning, which would
......@@ -890,6 +934,8 @@ AC_CONFIG_FILES([Makefile
src/bin/auth/Makefile
src/bin/auth/tests/Makefile
src/bin/auth/benchmarks/Makefile
src/bin/ddns/Makefile
src/bin/ddns/tests/Makefile
src/bin/dhcp6/Makefile
src/bin/dhcp6/tests/Makefile
src/bin/dhcp4/Makefile
......@@ -925,6 +971,8 @@ AC_CONFIG_FILES([Makefile
src/lib/python/isc/acl/tests/Makefile
src/lib/python/isc/util/Makefile
src/lib/python/isc/util/tests/Makefile
src/lib/python/isc/util/io/Makefile
src/lib/python/isc/util/io/tests/Makefile
src/lib/python/isc/datasrc/Makefile
src/lib/python/isc/datasrc/tests/Makefile
src/lib/python/isc/dns/Makefile
......@@ -993,6 +1041,7 @@ AC_CONFIG_FILES([Makefile
tests/tools/Makefile
tests/tools/badpacket/Makefile
tests/tools/badpacket/tests/Makefile
tests/tools/perfdhcp/Makefile
])
AC_OUTPUT([doc/version.ent
compatcheck/sqlite3-difftbl-check.py
......@@ -1002,6 +1051,7 @@ AC_OUTPUT([doc/version.ent
src/bin/cmdctl/run_b10-cmdctl.sh
src/bin/cmdctl/tests/cmdctl_test
src/bin/cmdctl/cmdctl.spec.pre
src/bin/ddns/ddns.py
src/bin/xfrin/tests/xfrin_test
src/bin/xfrin/xfrin.py
src/bin/xfrin/run_b10-xfrin.sh
......@@ -1135,6 +1185,7 @@ Flags:
CXXFLAGS: $CXXFLAGS
LDFLAGS: $LDFLAGS
B10_CXXFLAGS: $B10_CXXFLAGS
OS Family: $OS_TYPE
dnl includes too
Python: ${PYTHON_INCLUDES}
${PYTHON_CXXFLAGS}
......
......@@ -573,7 +573,7 @@ INPUT = ../src/lib/exceptions ../src/lib/cc \
../src/bin/auth ../src/bin/resolver ../src/lib/bench ../src/lib/log \
../src/lib/log/compiler ../src/lib/asiolink/ ../src/lib/nsas \
../src/lib/testutils ../src/lib/cache ../src/lib/server_common/ \
../src/bin/sockcreator/ ../src/lib/util/ \
../src/bin/sockcreator/ ../src/lib/util/ ../src/lib/util/io/ \
../src/lib/resolve ../src/lib/acl ../src/bin/dhcp6 ../src/lib/dhcp
# This tag can be used to specify the character encoding of the source files
......
......@@ -11,6 +11,8 @@ bind10-guide.html: bind10-guide.xml
xsltproc --novalid --xinclude --nonet \
--path $(top_builddir)/doc \
-o $@ \
--stringparam section.autolabel 1 \
--stringparam section.label.includes.component.label 1 \
--stringparam html.stylesheet $(srcdir)/bind10-guide.css \
http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl \
$(srcdir)/bind10-guide.xml
......
This diff is collapsed.
This diff is collapsed.
SUBDIRS = bind10 bindctl cfgmgr loadzone msgq host cmdctl auth xfrin xfrout \
usermgr zonemgr stats tests resolver sockcreator dhcp6 dhcp4
SUBDIRS = bind10 bindctl cfgmgr ddns loadzone msgq host cmdctl auth xfrin \
xfrout usermgr zonemgr stats tests resolver sockcreator dhcp4 dhcp6
check-recursive: all-recursive
......@@ -35,7 +35,6 @@
#include <server_common/portconfig.h>
using namespace std;
using boost::shared_ptr;
using namespace isc::dns;
using namespace isc::data;
using namespace isc::datasrc;
......@@ -56,7 +55,7 @@ public:
virtual void commit();
private:
AuthSrv& server_;
vector<shared_ptr<AuthConfigParser> > datasources_;
vector<boost::shared_ptr<AuthConfigParser> > datasources_;
set<string> configured_sources_;
};
......@@ -86,8 +85,8 @@ DatasourcesConfig::build(ConstElementPtr config_value) {
datasrc_type->stringValue() << "' already configured");
}
shared_ptr<AuthConfigParser> datasrc_config =
shared_ptr<AuthConfigParser>(
boost::shared_ptr<AuthConfigParser> datasrc_config =
boost::shared_ptr<AuthConfigParser>(
createAuthConfigParser(server_, string("datasources/") +
datasrc_type->stringValue(),
true));
......@@ -109,7 +108,8 @@ DatasourcesConfig::commit() {
// Currently memory data source for class IN is the only possibility.
server_.setInMemoryClient(RRClass::IN(), AuthSrv::InMemoryClientPtr());
BOOST_FOREACH(shared_ptr<AuthConfigParser> datasrc_config, datasources_) {
BOOST_FOREACH(boost::shared_ptr<AuthConfigParser> datasrc_config,
datasources_) {
datasrc_config->commit();
}
}
......@@ -163,7 +163,7 @@ MemoryDatasourceConfig::build(ConstElementPtr config_value) {
isc_throw(AuthConfigError, "Missing zone file for zone: "
<< origin->str());
}
shared_ptr<InMemoryZoneFinder> zone_finder(new
boost::shared_ptr<InMemoryZoneFinder> zone_finder(new
InMemoryZoneFinder(rrclass_,
Name(origin->stringValue())));
const result::Result result = memory_client_->addZone(zone_finder);
......@@ -327,7 +327,7 @@ configureAuthServer(AuthSrv& server, ConstElementPtr config_set) {
"Null pointer is passed to configuration parser");
}
typedef shared_ptr<AuthConfigParser> ParserPtr;
typedef boost::shared_ptr<AuthConfigParser> ParserPtr;
vector<ParserPtr> parsers;
typedef pair<string, ConstElementPtr> ConfigPair;
try {
......
......@@ -76,7 +76,6 @@ using namespace isc::xfr;
using namespace isc::asiolink;
using namespace isc::asiodns;
using namespace isc::server_common::portconfig;
using boost::shared_ptr;
class AuthSrvImpl {
private:
......@@ -124,7 +123,7 @@ public:
AddressList listen_addresses_;
/// The TSIG keyring
const shared_ptr<TSIGKeyRing>* keyring_;
const boost::shared_ptr<TSIGKeyRing>* keyring_;
/// Bind the ModuleSpec object in config_session_ with
/// isc:config::ModuleSpec::validateStatistics.
......@@ -228,12 +227,13 @@ private:
AuthSrv* server_;
};
AuthSrv::AuthSrv(const bool use_cache, AbstractXfroutClient& xfrout_client) :
impl_(new AuthSrvImpl(use_cache, xfrout_client)),
checkin_(new ConfigChecker(this)),
dns_lookup_(new MessageLookup(this)),
dns_answer_(new MessageAnswer(this))
{}
AuthSrv::AuthSrv(const bool use_cache, AbstractXfroutClient& xfrout_client)
{
impl_ = new AuthSrvImpl(use_cache, xfrout_client);
checkin_ = new ConfigChecker(this);
dns_lookup_ = new MessageLookup(this);
dns_answer_ = new MessageAnswer(this);
}
void
AuthSrv::stop() {
......@@ -786,6 +786,6 @@ AuthSrv::setDNSService(isc::asiodns::DNSService& dnss) {
}
void
AuthSrv::setTSIGKeyRing(const shared_ptr<TSIGKeyRing>* keyring) {
AuthSrv::setTSIGKeyRing(const boost::shared_ptr<TSIGKeyRing>* keyring) {
impl_->keyring_ = keyring;
}
......@@ -32,7 +32,6 @@
#include <auth/command.h>
using boost::scoped_ptr;
using boost::shared_ptr;
using namespace isc::auth;
using namespace isc::config;
using namespace isc::data;
......@@ -136,7 +135,7 @@ public:
// that doesn't block other server operations.
// TODO: we may (should?) want to check the "last load time" and
// the timestamp of the file and skip loading if the file isn't newer.
shared_ptr<InMemoryZoneFinder> zone_finder(
boost::shared_ptr<InMemoryZoneFinder> zone_finder(
new InMemoryZoneFinder(old_zone_finder->getClass(),
old_zone_finder->getOrigin()));
zone_finder->load(old_zone_finder->getFileName());
......@@ -147,7 +146,7 @@ public:
private:
// zone finder to be updated with the new file.
shared_ptr<InMemoryZoneFinder> old_zone_finder;
boost::shared_ptr<InMemoryZoneFinder> old_zone_finder;
// A helper private method to parse and validate command parameters.
// On success, it sets 'old_zone_finder' to the zone to be updated.
......
......@@ -15,6 +15,8 @@
#include <algorithm> // for std::max
#include <vector>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <dns/message.h>
#include <dns/rcode.h>
......@@ -67,7 +69,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find A rrset
if (qname_ != qname || qtype_ != RRType::A()) {
ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(), NULL,
ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(),
options | dnssec_opt_);
if (a_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
......@@ -78,7 +80,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find AAAA rrset
if (qname_ != qname || qtype_ != RRType::AAAA()) {
ZoneFinder::FindResult aaaa_result =
zone.find(qname, RRType::AAAA(), NULL, options | dnssec_opt_);
zone.find(qname, RRType::AAAA(), options | dnssec_opt_);
if (aaaa_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
boost::const_pointer_cast<RRset>(aaaa_result.rrset),
......@@ -90,7 +92,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
void
Query::addSOA(ZoneFinder& finder) {
ZoneFinder::FindResult soa_result(finder.find(finder.getOrigin(),
RRType::SOA(), NULL, dnssec_opt_));
RRType::SOA(), dnssec_opt_));
if (soa_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoSOA, "There's no SOA record in zone " <<
finder.getOrigin().toText());
......@@ -146,7 +148,7 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
// otherwise we shouldn't have got NXDOMAIN for the original query in
// the first place).
const ZoneFinder::FindResult fresult = finder.find(wildname,
RRType::NSEC(), NULL,
RRType::NSEC(),
dnssec_opt_);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
......@@ -171,7 +173,7 @@ Query::addWildcardProof(ZoneFinder& finder) {
// substitution. Confirm that by specifying NO_WILDCARD. It should result
// in NXDOMAIN and an NSEC RR that proves it should be returned.
const ZoneFinder::FindResult fresult =
finder.find(qname_, RRType::NSEC(), NULL,
finder.find(qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
......@@ -194,7 +196,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
boost::const_pointer_cast<RRset>(nsec), dnssec_);
const ZoneFinder::FindResult fresult =
finder.find(qname_, RRType::NSEC(), NULL,
finder.find(qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
......@@ -213,8 +215,7 @@ void
Query::addAuthAdditional(ZoneFinder& finder) {
// Fill in authority and addtional sections.
ZoneFinder::FindResult ns_result = finder.find(finder.getOrigin(),
RRType::NS(), NULL,
dnssec_opt_);
RRType::NS(), dnssec_opt_);
// zone origin name should have NS records
if (ns_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoApexNS, "There's no apex NS records in zone " <<
......@@ -229,7 +230,6 @@ Query::addAuthAdditional(ZoneFinder& finder) {
void
Query::process() {
bool keep_doing = true;
const bool qtype_is_any = (qtype_ == RRType::ANY());
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
......@@ -251,147 +251,151 @@ Query::process() {
// Found a zone which is the nearest ancestor to QNAME, set the AA bit
response_.setHeaderFlag(Message::HEADERFLAG_AA);
response_.setRcode(Rcode::NOERROR());
while (keep_doing) {
keep_doing = false;
std::auto_ptr<RRsetList> target(qtype_is_any ? new RRsetList : NULL);
const ZoneFinder::FindResult db_result(
zfinder.find(qname_, qtype_, target.get(), dnssec_opt_));
switch (db_result.code) {
case ZoneFinder::DNAME: {
// First, put the dname into the answer
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
std::vector<ConstRRsetPtr> target;
boost::function0<ZoneFinder::FindResult> find;
if (qtype_is_any) {
find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_,
boost::ref(target), dnssec_opt_);
} else {
find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_,
dnssec_opt_);
}
ZoneFinder::FindResult db_result(find());
switch (db_result.code) {
case ZoneFinder::DNAME: {
// First, put the dname into the answer
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
*
* FIXME: Other way to prevent this should be done
*/
assert(db_result.rrset->getRdataCount() > 0);
// Get the data of DNAME
const rdata::generic::DNAME& dname(
dynamic_cast<const rdata::generic::DNAME&>(
db_result.rrset->getRdataIterator()->getCurrent()));
// The yet unmatched prefix dname
const Name prefix(qname_.split(0, qname_.getLabelCount() -
db_result.rrset->getName().getLabelCount()));
// If we put it together, will it be too long?
// (The prefix contains trailing ., which will be removed
if (prefix.getLength() - Name::ROOT_NAME().getLength() +
dname.getDname().getLength() > Name::MAX_WIRE) {
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
*
* FIXME: Other way to prevent this should be done
* In case the synthesized name is too long, section 4.1
* of RFC 2672 mandates we return YXDOMAIN.
*/
assert(db_result.rrset->getRdataCount() > 0);
// Get the data of DNAME
const rdata::generic::DNAME& dname(
dynamic_cast<const rdata::generic::DNAME&>(
db_result.rrset->getRdataIterator()->getCurrent()));
// The yet unmatched prefix dname
const Name prefix(qname_.split(0, qname_.getLabelCount() -
db_result.rrset->getName().getLabelCount()));
// If we put it together, will it be too long?
// (The prefix contains trailing ., which will be removed
if (prefix.getLength() - Name::ROOT_NAME().getLength() +
dname.getDname().getLength() > Name::MAX_WIRE) {
/*
* In case the synthesized name is too long, section 4.1
* of RFC 2672 mandates we return YXDOMAIN.
*/
response_.setRcode(Rcode::YXDOMAIN());
return;
}
// The new CNAME we are creating (it will be unsigned even
// with DNSSEC, the DNAME is signed and it can be validated
// by that)
RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(),
RRType::CNAME(), db_result.rrset->getTTL()));
// Construct the new target by replacing the end
cname->addRdata(rdata::generic::CNAME(qname_.split(0,
qname_.getLabelCount() -
db_result.rrset->getName().getLabelCount()).
concatenate(dname.getDname())));
response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
break;
response_.setRcode(Rcode::YXDOMAIN());
return;
}
case ZoneFinder::CNAME:
case ZoneFinder::WILDCARD_CNAME:
/*
* We don't do chaining yet. Therefore handling a CNAME is
* mostly the same as handling SUCCESS, but we didn't get
* what we expected. It means no exceptions in ANY or NS
* on the origin (though CNAME in origin is probably
* forbidden anyway).
*
* So, just put it there.
*/
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
// The new CNAME we are creating (it will be unsigned even
// with DNSSEC, the DNAME is signed and it can be validated
// by that)
RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(),
RRType::CNAME(), db_result.rrset->getTTL()));
// Construct the new target by replacing the end
cname->addRdata(rdata::generic::CNAME(qname_.split(0,
qname_.getLabelCount() -
db_result.rrset->getName().getLabelCount()).
concatenate(dname.getDname())));
response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
break;
}
case ZoneFinder::CNAME:
case ZoneFinder::WILDCARD_CNAME:
/*
* We don't do chaining yet. Therefore handling a CNAME is
* mostly the same as handling SUCCESS, but we didn't get
* what we expected. It means no exceptions in ANY or NS
* on the origin (though CNAME in origin is probably
* forbidden anyway).
*
* So, just put it there.
*/
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if (dnssec_ && db_result.code == ZoneFinder::WILDCARD_CNAME) {
addWildcardProof(*result.zone_finder);
}
break;
case ZoneFinder::SUCCESS:
case ZoneFinder::WILDCARD:
if (qtype_is_any) {
// If quety type is ANY, insert all RRs under the domain
// into answer section.
BOOST_FOREACH(RRsetPtr rrset, *target) {
response_.addRRset(Message::SECTION_ANSWER, rrset,
dnssec_);
// Handle additional for answer section
addAdditional(*result.zone_finder, *rrset.get());
}
} else {
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if (dnssec_ && db_result.code == ZoneFinder::WILDCARD_CNAME) {
addWildcardProof(*result.zone_finder);
}
break;
case ZoneFinder::SUCCESS:
case ZoneFinder::WILDCARD:
if (qtype_is_any) {
// If quety type is ANY, insert all RRs under the domain
// into answer section.
BOOST_FOREACH(ConstRRsetPtr rrset, target) {
response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
boost::const_pointer_cast<RRset>(rrset), dnssec_);
// Handle additional for answer section
addAdditional(*result.zone_finder, *db_result.rrset);
addAdditional(*result.zone_finder, *rrset.get());
}
// If apex NS records haven't been provided in the answer
// section, insert apex NS records into the authority section
// and AAAA/A RRS of each of the NS RDATA into the additional
// section.
if (qname_ != result.zone_finder->getOrigin() ||
db_result.code != ZoneFinder::SUCCESS ||
(qtype_ != RRType::NS() && !qtype_is_any))
{
addAuthAdditional(*result.zone_finder);
}
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
if (dnssec_ && db_result.code == ZoneFinder::WILDCARD) {
addWildcardProof(*result.zone_finder);
}
break;
case ZoneFinder::DELEGATION:
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);