Commit 9b2b249d authored by Stephen Morris's avatar Stephen Morris
Browse files

Merge branch 'master' into trac1383

parents c0be7a6c 45274924
341. [func] tomek
libdhcp++: Support for handling both IPv4 and IPv6 added.
Also added support for binding IPv4 sockets.
(Trac #1238, git 86a4ce45115dab4d3978c36dd2dbe07edcac02ac)
340. [build] jelte
Fixed several linker issues related to recent gcc versions, botan
and gtest.
(Trac #1442, git 91fb141bfb3aadfdf96f13e157a26636f6e9f9e3)
339. [bug] jinmei
libxfr, used by b10-auth to share TCP sockets with b10-xfrout,
incorrectly propagated ASIO specific exceptions to the application
if the given file name was too long. This could lead to
unexpected shut down of b10-auth.
(Trac #1387, git a5e9d9176e9c60ef20c0f5ef59eeb6838ed47ab2)
338. [bug] jinmei
b10-xfrin didn't check SOA serials of SOA and IXFR responses,
which resulted in unnecessary transfer or unexpected IXFR
timeouts (these issues were not overlooked but deferred to be
fixed until #1278 was completed). Validation on responses to SOA
queries were tightened, too.
(Trac #1299, git 6ff03bb9d631023175df99248e8cc0cda586c30a)
337. [func] tomek
libdhcp++: Support for DHCPv4 option that can store a single
address or a list of IPv4 addresses added. Support for END option
added.
(Trac #1350, git cc20ff993da1ddb1c6e8a98370438b45a2be9e0a)
336. [func] jelte
libdns++ (and its python wrapper) now includes a class Serial, for
SOA SERIAL comparison and addition. Operations on instances of this
class follow the specification from RFC 1982.
Rdata::SOA::getSerial() now returns values of this type (and not
uint32_t).
(Trac #1278, git 2ae72d76c74f61a67590722c73ebbf631388acbd)
335. [bug]* jelte
The DataSourceClientContainer class that dynamically loads
datasource backend libraries no longer provides just a .so file name
to its call to dlopen(), but passes it an absolute path. This means
that it is no longer an system implementation detail that depends on
[DY]LD_LIBRARY_PATH which file is chosen, should there be multiple
options (for instance, when test-running a new build while a
different version is installed).
These loadable libraries are also no longer installed in the default
library path, but in a subdirectory of the libexec directory of the
target ($prefix/libexec/[version]/backends).
This also removes the need to handle b10-xfin and b10-xfrout as
'special' hardcoded components, and they are now started as regular
components as dictated by the configuration of the boss process.
(Trac #1292, git 83ce13c2d85068a1bec015361e4ef8c35590a5d0)
334. [bug] jinmei
b10-xfrout could potentially create an overflow response message
(exceeding the 64KB max) or could create unnecessarily small
messages. The former was actually unlikely to happen due to the
effect of name compression, and the latter was marginal and at least
shouldn't cause an interoperability problem, but these were still
potential problems and were fixed.
(Trac #1389, git 3fdce88046bdad392bd89ea656ec4ac3c858ca2f)
333. [bug] dvv
Solaris needs "-z now" to force non-lazy binding and prevent g++ static
initialization code from deadlocking.
(Trac #1439, git c789138250b33b6b08262425a08a2a0469d90433)
332. [bug] vorner
C++ exceptions in the isc.dns.Rdata wrapper are now converted
to python ones instead of just aborting the interpretter.
......@@ -33,7 +102,7 @@ bind10-devel-20111128 released on November 28, 2011
always respond to IXFR requests according to RFC1995).
(Trac #1371 and #1372, git 80c131f5b0763753d199b0fb9b51f10990bcd92b)
326. [build]* jinmei
326. [build]* jinmei
Added a check script for the SQLite3 schema version. It will be
run at the beginning of 'make install', and if it detects an old
version of schema, installation will stop. You'll then need to
......
......@@ -96,6 +96,8 @@ case "$host" in
# Solaris requires special definitions to get some standard libraries
# (e.g. getopt(3)) available with common used header files.
CPPFLAGS="$CPPFLAGS -D_XPG4_2 -D__EXTENSIONS__"
# "now" binding is necessary to prevent deadlocks in C++ static initialization code
LDFLAGS="$LDFLAGS -z now"
;;
*-apple-darwin*)
# libtool doesn't work perfectly with Darwin: libtool embeds the
......@@ -478,23 +480,33 @@ else
fi
fi
BOTAN_LDFLAGS=`${BOTAN_CONFIG} --libs`
BOTAN_LIBS=`${BOTAN_CONFIG} --libs`
BOTAN_INCLUDES=`${BOTAN_CONFIG} --cflags`
# We expect botan-config --libs to contain -L<path_to_libbotan>, but
# this is not always the case. As a heuristics workaround we add
# -L`botan-config --prefix/lib` in this case. Same for BOTAN_INCLUDES
# (but using include instead of lib) below.
# -L`botan-config --prefix/lib` in this case (if not present already).
# Same for BOTAN_INCLUDES (but using include instead of lib) below.
if [ $BOTAN_CONFIG --prefix >/dev/null 2>&1 ] ; then
echo ${BOTAN_LDFLAGS} | grep -- -L > /dev/null || \
BOTAN_LDFLAGS="-L`${BOTAN_CONFIG} --prefix`/lib ${BOTAN_LDFLAGS}"
echo ${BOTAN_LIBS} | grep -- -L > /dev/null || \
BOTAN_LIBS="-L`${BOTAN_CONFIG} --prefix`/lib ${BOTAN_LIBS}"
echo ${BOTAN_INCLUDES} | grep -- -I > /dev/null || \
BOTAN_INCLUDES="-I`${BOTAN_CONFIG} --prefix`/include ${BOTAN_INCLUDES}"
fi
# botan-config script (and the way we call pkg-config) returns -L and -l
# as one string, but we need them in separate values
BOTAN_LDFLAGS=
BOTAN_NEWLIBS=
for flag in ${BOTAN_LIBS}; do
BOTAN_LDFLAGS="${BOTAN_LDFLAGS} `echo $flag | sed -ne '/^\(\-L\)/p'`"
BOTAN_LIBS="${BOTAN_LIBS} `echo $flag | sed -ne '/^\(\-l\)/p'`"
done
# See python_rpath for some info on why we do this
if test $rpath_available = yes; then
BOTAN_RPATH=
for flag in ${BOTAN_LDFLAGS}; do
for flag in ${BOTAN_LIBS}; do
BOTAN_RPATH="${BOTAN_RPATH} `echo $flag | sed -ne 's/^\(\-L\)/-R/p'`"
done
AC_SUBST(BOTAN_RPATH)
......@@ -510,13 +522,13 @@ AC_SUBST(BOTAN_RPATH)
fi
AC_SUBST(BOTAN_LDFLAGS)
AC_SUBST(BOTAN_LIBS)
AC_SUBST(BOTAN_INCLUDES)
CPPFLAGS_SAVED=$CPPFLAGS
CPPFLAGS="$BOTAN_INCLUDES $CPPFLAGS"
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$BOTAN_LDFLAGS $LDFLAGS"
LIBS_SAVED="$LIBS"
LIBS="$LIBS $BOTAN_LIBS"
AC_CHECK_HEADERS([botan/botan.h],,AC_MSG_ERROR([Missing required header files.]))
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <botan/botan.h>
......@@ -531,7 +543,7 @@ AC_LINK_IFELSE(
AC_MSG_ERROR([Needs Botan library 1.8 or higher])]
)
CPPFLAGS=$CPPFLAGS_SAVED
LDFLAGS=$LDFLAGS_SAVED
LIBS=$LIBS_SAVED
# Check for log4cplus
log4cplus_path="yes"
......@@ -543,7 +555,7 @@ if test "${log4cplus_path}" = "no" ; then
AC_MSG_ERROR([Need log4cplus])
elif test "${log4cplus_path}" != "yes" ; then
LOG4CPLUS_INCLUDES="-I${log4cplus_path}/include"
LOG4CPLUS_LDFLAGS="-L${log4cplus_path}/lib"
LOG4CPLUS_LIBS="-L${log4cplus_path}/lib"
else
# If not specified, try some common paths.
log4cplusdirs="/usr/local /usr/pkg /opt /opt/local"
......@@ -551,21 +563,21 @@ else
do
if test -f $d/include/log4cplus/logger.h; then
LOG4CPLUS_INCLUDES="-I$d/include"
LOG4CPLUS_LDFLAGS="-L$d/lib"
LOG4CPLUS_LIBS="-L$d/lib"
break
fi
done
fi
LOG4CPLUS_LDFLAGS="$LOG4CPLUS_LDFLAGS -llog4cplus $MULTITHREADING_FLAG"
LOG4CPLUS_LIBS="$LOG4CPLUS_LIBS -llog4cplus $MULTITHREADING_FLAG"
AC_SUBST(LOG4CPLUS_LDFLAGS)
AC_SUBST(LOG4CPLUS_LIBS)
AC_SUBST(LOG4CPLUS_INCLUDES)
CPPFLAGS_SAVED=$CPPFLAGS
CPPFLAGS="$LOG4CPLUS_INCLUDES $CPPFLAGS"
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LOG4CPLUS_LDFLAGS $LDFLAGS"
LIBS_SAVED="$LIBS"
LIBS="$LOG4CPLUS_LIBS $LIBS"
AC_CHECK_HEADERS([log4cplus/logger.h],,AC_MSG_ERROR([Missing required header files.]))
AC_LINK_IFELSE(
......@@ -580,7 +592,7 @@ AC_LINK_IFELSE(
)
CPPFLAGS=$CPPFLAGS_SAVED
LDFLAGS=$LDFLAGS_SAVED
LIBS=$LIBS_SAVED
#
# Configure Boost header path
......@@ -673,6 +685,13 @@ else
AM_CONDITIONAL(NEED_LIBBOOST_THREAD, test "${use_boost_threads}" = "yes")
fi
# I can't get some of the #include <asio.hpp> right without this
# TODO: find the real cause of asio/boost wanting pthreads
# (this currently only occurs for src/lib/cc/session_unittests)
PTHREAD_LDFLAGS=
AC_CHECK_LIB(pthread, pthread_create,[ PTHREAD_LDFLAGS=-lpthread ], [])
AC_SUBST(PTHREAD_LDFLAGS)
AC_SUBST(MULTITHREADING_FLAG)
#
# Check availability of gtest, which will be used for unit tests.
......@@ -709,6 +728,48 @@ then
GTEST_LDFLAGS="-L$dir/lib"
GTEST_LDADD="-lgtest"
GTEST_FOUND="true"
# There is no gtest-config script on this
# system, which is supposed to inform us
# whether we need pthreads as well (a
# gtest compile-time option). So we still
# need to test that manually.
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $GTEST_INCLUDES"
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $GTEST_LDFLAGS"
LIBS_SAVED=$LIBS
LIBS="$LIBS $GTEST_LDADD"
AC_MSG_CHECKING([Checking whether gtest tests need pthreads])
# First try to compile without pthreads
AC_TRY_LINK([
#include <gtest/gtest.h>
],[
int i = 0;
char* c = NULL;
::testing::InitGoogleTest(&i, &c);
return (0);
],
[ AC_MSG_RESULT(no) ],
[
LIBS="$SAVED_LIBS $GTEST_LDADD $PTHREAD_LDFLAGS"
# Now try to compile with pthreads
AC_TRY_LINK([
#include <gtest/gtest.h>
],[
int i = 0;
char* c = NULL;
::testing::InitGoogleTest(&i, &c);
return (0);
],
[ AC_MSG_RESULT(yes)
GTEST_LDADD="$GTEST_LDADD $PTHREAD_LDFLAGS"
],
# Apparently we can't compile it at all
[ AC_MSG_ERROR(unable to compile with gtest) ])
])
CPPFLAGS=$CPPFLAGS_SAVED
LDFLAGS=$LDFLAGS_SAVED
LIBS=$LIBS_SAVED
break
fi
done
......@@ -735,15 +796,6 @@ if test "x$HAVE_PKG_CONFIG" = "xno" ; then
fi
PKG_CHECK_MODULES(SQLITE, sqlite3 >= 3.3.9, enable_features="$enable_features SQLite3")
# I can't get some of the #include <asio.hpp> right without this
# TODO: find the real cause of asio/boost wanting pthreads
# (this currently only occurs for src/lib/cc/session_unittests)
PTHREAD_LDFLAGS=
AC_CHECK_LIB(pthread, pthread_create,[ PTHREAD_LDFLAGS=-lpthread ], [])
AC_SUBST(PTHREAD_LDFLAGS)
AC_SUBST(MULTITHREADING_FLAG)
#
# ASIO: we extensively use it as the C++ event management module.
#
......@@ -910,6 +962,7 @@ AC_CONFIG_FILES([Makefile
src/lib/datasrc/tests/Makefile
src/lib/datasrc/tests/testdata/Makefile
src/lib/xfr/Makefile
src/lib/xfr/tests/Makefile
src/lib/log/Makefile
src/lib/log/compiler/Makefile
src/lib/log/tests/Makefile
......@@ -990,6 +1043,7 @@ AC_OUTPUT([doc/version.ent
src/lib/python/bind10_config.py
src/lib/cc/session_config.h.pre
src/lib/cc/tests/session_unittests_config.h
src/lib/datasrc/datasrc_config.h.pre
src/lib/log/tests/console_test.sh
src/lib/log/tests/destination_test.sh
src/lib/log/tests/init_logger_test.sh
......@@ -1084,8 +1138,9 @@ dnl includes too
Boost: ${BOOST_INCLUDES}
Botan: ${BOTAN_INCLUDES}
${BOTAN_LDFLAGS}
${BOTAN_LIBS}
Log4cplus: ${LOG4CPLUS_INCLUDES}
${LOG4CPLUS_LDFLAGS}
${LOG4CPLUS_LIBS}
SQLite: $SQLITE_CFLAGS
$SQLITE_LIBS
......
......@@ -32,8 +32,8 @@ query_bench_LDADD += $(top_builddir)/src/lib/cc/libcc.la
query_bench_LDADD += $(top_builddir)/src/lib/xfr/libxfr.la
query_bench_LDADD += $(top_builddir)/src/lib/log/liblog.la
query_bench_LDADD += $(top_builddir)/src/lib/nsas/libnsas.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
query_bench_LDADD += $(top_builddir)/src/lib/asiolink/libasiolink.la
query_bench_LDADD += $(top_builddir)/src/lib/server_common/libserver_common.la
query_bench_LDADD += $(top_builddir)/src/lib/asiodns/libasiodns.la
query_bench_LDADD += $(SQLITE_LIBS)
......@@ -117,7 +117,6 @@ void
Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
if (nsec->getRdataCount() == 0) {
isc_throw(BadNSEC, "NSEC for NXDOMAIN is empty");
return;
}
// Add the NSEC proving NXDOMAIN to the authority section.
......@@ -152,7 +151,6 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
isc_throw(BadNSEC, "Unexpected result for wildcard NXDOMAIN proof");
return;
}
// Add the (no-) wildcard proof only when it's different from the NSEC
......@@ -178,7 +176,6 @@ Query::addWildcardProof(ZoneFinder& finder) {
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
isc_throw(BadNSEC, "Unexpected result for wildcard proof");
return;
}
response_.addRRset(Message::SECTION_AUTHORITY,
boost::const_pointer_cast<RRset>(fresult.rrset),
......@@ -186,12 +183,11 @@ Query::addWildcardProof(ZoneFinder& finder) {
}
void
Query::addWildcardNxrrsetProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
// There should be one NSEC RR which was found in the zone to prove
// that there is not matched <QNAME,QTYPE> via wildcard expansion.
if (nsec->getRdataCount() == 0) {
isc_throw(BadNSEC, "NSEC for WILDCARD_NXRRSET is empty");
return;
}
// Add this NSEC RR to authority section.
response_.addRRset(Message::SECTION_AUTHORITY,
......@@ -203,7 +199,6 @@ Query::addWildcardNxrrsetProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
isc_throw(BadNSEC, "Unexpected result for no match QNAME proof");
return;
}
if (nsec->getName() != fresult.rrset->getName()) {
......@@ -387,7 +382,7 @@ Query::process() {
case ZoneFinder::WILDCARD_NXRRSET:
addSOA(*result.zone_finder);
if (dnssec_ && db_result.rrset) {
addWildcardNxrrsetProof(zfinder,db_result.rrset);
addWildcardNXRRSETProof(zfinder, db_result.rrset);
}
break;
default:
......
......@@ -91,7 +91,7 @@ private:
/// query is to be found.
/// \param nsec The RRset (NSEC RR) which proved that there is no matched
/// <QNAME,QTTYPE>.
void addWildcardNxrrsetProof(isc::datasrc::ZoneFinder& finder,
void addWildcardNXRRSETProof(isc::datasrc::ZoneFinder& finder,
isc::dns::ConstRRsetPtr nsec);
/// \brief Look up additional data (i.e., address records for the names
......
......@@ -109,6 +109,13 @@ const char* const wild_txt_next =
"www.uwild.example.com. 3600 IN A 192.0.2.11\n";
const char* const nsec_wild_txt_next =
"www.uwild.example.com. 3600 IN NSEC *.wild.example.com. A NSEC RRSIG\n";
// Wildcard empty
const char* const empty_txt = "b.*.t.example.com. 3600 IN A 192.0.2.13\n";
const char* const nsec_empty_txt =
"b.*.t.example.com. 3600 IN NSEC *.uwild.example.com. A NSEC RRSIG\n";
const char* const empty_prev_txt = "t.example.com. 3600 IN A 192.0.2.15\n";
const char* const nsec_empty_prev_txt =
"t.example.com. 3600 IN NSEC b.*.t.example.com. A NSEC RRSIG\n";
// Used in NXDOMAIN proof test. We are going to test some unusual case where
// the best possible wildcard is below the "next domain" of the NSEC RR that
// proves the NXDOMAIN, i.e.,
......@@ -188,8 +195,9 @@ public:
nsec_apex_txt << nsec_mx_txt << nsec_no_txt << nsec_nz_txt <<
nsec_nxdomain_txt << nsec_www_txt << nonsec_a_txt <<
wild_txt << nsec_wild_txt << cnamewild_txt << nsec_cnamewild_txt <<
wild_txt_nxrrset<<nsec_wild_txt_nxrrset<<wild_txt_next<<
nsec_wild_txt_next;
wild_txt_nxrrset << nsec_wild_txt_nxrrset << wild_txt_next <<
nsec_wild_txt_next << empty_txt << nsec_empty_txt <<
empty_prev_txt << nsec_empty_prev_txt;
masterLoad(zone_stream, origin_, rrclass_,
boost::bind(&MockZoneFinder::loadRRset, this, _1));
......@@ -407,24 +415,45 @@ MockZoneFinder::find(const Name& name, const RRType& type,
// due to the existence of closer name.
if ((options & NO_WILDCARD) == 0) {
const Name wild_suffix(name.split(1));
// Unit Tests use those domains for Wildcard test.
if (name.equals(Name("www.wild.example.com"))||
name.equals(Name("www1.uwild.example.com"))) {
name.equals(Name("www1.uwild.example.com"))||
name.equals(Name("a.t.example.com"))) {
if (name.compare(wild_suffix).getRelation() ==
NameComparisonResult::SUBDOMAIN) {
domain = domains_.find(Name("*").concatenate(wild_suffix));
assert(domain != domains_.end());
RRsetStore::const_iterator found_rrset = domain->second.find(type);
if (found_rrset != domain->second.end()) {
// Matched the QNAME
if (domain != domains_.end()) {
RRsetStore::const_iterator found_rrset =
domain->second.find(type);
// Matched the QTYPE
if(found_rrset != domain->second.end()) {
return (FindResult(WILDCARD,
substituteWild(*found_rrset->second, name)));
} else {
found_rrset = domain->second.find(RRType::NSEC());
assert(found_rrset != domain->second.end());
Name newName = Name("*").concatenate(wild_suffix);
return (FindResult(WILDCARD_NXRRSET,
} else {
// No matched QTYPE, this case is for WILDCARD_NXRRSET
found_rrset = domain->second.find(RRType::NSEC());
assert(found_rrset != domain->second.end());
Name newName = Name("*").concatenate(wild_suffix);
return (FindResult(WILDCARD_NXRRSET,
substituteWild(*found_rrset->second,newName)));
}
} else {
// This is empty non terminal name case on wildcard.
Name emptyName = Name("*").concatenate(wild_suffix);
for (Domains::reverse_iterator it = domains_.rbegin();
it != domains_.rend();
++it) {
RRsetStore::const_iterator nsec_it;
if ((*it).first < emptyName &&
(nsec_it = (*it).second.find(RRType::NSEC()))
!= (*it).second.end()) {
return (FindResult(WILDCARD_NXRRSET,
(*nsec_it).second));
}
}
}
return (FindResult(WILDCARD_NXRRSET,RRsetPtr()));
}
}
const Name cnamewild_suffix("cnamewild.example.com");
......@@ -955,7 +984,7 @@ TEST_F(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
string(nsec_wild_txt) +
string(nsec_wild_txt) +
string("*.wild.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC")+"\n").c_str(),
NULL, mock_finder->getOrigin());
......@@ -967,11 +996,11 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC) {
// one proves NXDOMAIN and the other proves non existence RRSETs of wildcard.
Query(memory_client, Name("www1.uwild.example.com"), RRType::TXT(), response,
true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
string(nsec_wild_txt_nxrrset) +
string(nsec_wild_txt_nxrrset) +
string("*.uwild.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC")+"\n" +
string(nsec_wild_txt_next) +
......@@ -979,6 +1008,26 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC) {
getCommonRRSIGText("NSEC") + "\n").c_str(),
NULL, mock_finder->getOrigin());
}
TEST_F(QueryTest, wildcardEmptyWithNSEC) {
// WILDCARD_EMPTY with DNSSEC proof. We should have SOA, NSEC that proves the
// NXDOMAIN and their RRSIGs. In this case we need two NSEC RRs,
// one proves NXDOMAIN and the other proves non existence wildcard.
Query(memory_client, Name("a.t.example.com"), RRType::A(), response,
true).process();
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
string(nsec_empty_prev_txt) +
string("t.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC")+"\n" +
string(nsec_empty_txt) +
string("b.*.t.example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("NSEC")+"\n").c_str(),
NULL, mock_finder->getOrigin());
}
/*
* This tests that when there's no SOA and we need a negative answer. It should
* throw in that case.
......
......@@ -99,6 +99,12 @@ The boss module is sending a kill signal to process with the given name,
as part of the process of killing all started processes during a failed
startup, as described for BIND10_KILLING_ALL_PROCESSES
% BIND10_LOST_SOCKET_CONSUMER consumer %1 of sockets disconnected, considering all its sockets closed
A connection from one of the applications which requested a socket was
closed. This means the application has terminated, so all the sockets it was
using are now closed and bind10 process can release them as well, unless the
same sockets are used by yet another application.
% BIND10_MSGQ_ALREADY_RUNNING msgq daemon already running, cannot start
There already appears to be a message bus daemon running. Either an
old process was not shut down correctly, and needs to be killed, or
......@@ -110,6 +116,11 @@ While listening on the message bus channel for messages, it suddenly
disappeared. The msgq daemon may have died. This might lead to an
inconsistent state of the system, and BIND 10 will now shut down.
% BIND10_NO_SOCKET couldn't send a socket for token %1 because of error: %2
An error occurred when the bind10 process was asked to send a socket file
descriptor. The error is mentioned, most common reason is that the request
is invalid and may not come from bind10 process at all.
% BIND10_PROCESS_ENDED process %2 of %1 ended with status %3
This indicates a process started previously terminated. The process id
and component owning the process are indicated, as well as the exit code.
......
......@@ -72,6 +72,9 @@ import isc.log
from isc.log_messages.bind10_messages import *
import isc.bind10.component
import isc.bind10.special_component
import isc.bind10.socket_cache
import libutil_io_python
import tempfile
isc.log.init("b10-boss")
logger = isc.log.Logger("boss")
......@@ -81,6 +84,10 @@ logger = isc.log.Logger("boss")
DBG_PROCESS = logger.DBGLVL_TRACE_BASIC
DBG_COMMANDS = logger.DBGLVL_TRACE_DETAIL
# Messages sent over the unix domain socket to indicate if it is followed by a real socket
CREATOR_SOCKET_OK = "1\n"
CREATOR_SOCKET_UNAVAILABLE = "0\n"
# Assign this process some longer name
isc.util.process.rename(sys.argv[0])
......@@ -241,6 +248,12 @@ class BoB:
# If -v was set, enable full debug logging.
if self.verbose:
logger.set_severity("DEBUG", 99)
# This is set in init_socket_srv
self._socket_path = None
self._socket_cache = None
self._tmpdir = None
self._srv_socket = None
self._unix_sockets = {}
def __propagate_component_config(self, config):
comps = dict(config)
......@@ -315,6 +328,18 @@ class BoB:
elif command == "show_processes":
answer = isc.config.ccsession. \
create_answer(0, self.get_processes())
elif command == "get_socket":
answer = self._get_socket(args)
elif command == "drop_socket":
if "token" not in args:
answer = isc.config.ccsession. \
create_answer(1, "Missing token parameter")
else:
try:
self._socket_cache.drop_socket(args["token"])
answer = isc.config.ccsession.create_answer(0)
except Exception as e:
answer = isc.config.ccsession.create_answer(1, str(e))
else:
answer = isc.config.ccsession.create_answer(1,
"Unknown command")
......@@ -574,33 +599,6 @@ class BoB:
# ... and start
return self.start_process("b10-resolver", resargs, self.c_channel_env)
def __ld_path_hack(self):
# XXX: a quick-hack workaround. xfrin/out will implicitly use
# dynamically loadable data source modules, which will be installed in
# $(libdir).
# On some OSes (including MacOS X and *BSDs) the main process (python)
# cannot find the modules unless they are located in a common shared
# object path or a path in the (DY)LD_LIBRARY_PATH. We should seek
# a cleaner solution, but for a short term workaround we specify the
# path here, unconditionally, and without even bothering which
# environment variable should be used.
#
# We reuse the ADD_LIBEXEC_PATH variable to see whether we need to
# do this, as the conditions that make this workaround needed are
# the same as for the libexec path addition
# TODO: Once #1292 is finished, remove this method and the special
# component, use it as normal component.
env = dict(self.c_channel_env)
if ADD_LIBEXEC_PATH:
cur_path = os.getenv('DYLD_LIBRARY_PATH')
cur_path = '' if cur_path is None else ':' + cur_path
env['DYLD_LIBRARY_PATH'] = "@@LIBDIR@@" + cur_path
cur_path = os.getenv('LD_LIBRARY_PATH')
cur_path = '' if cur_path is None else ':' + cur_path
env['LD_LIBRARY_PATH'] = "@@LIBDIR@@" + cur_path
return env
def start_cmdctl(self):
"""
Starts the command control process
......@@ -613,22 +611,6 @@ class BoB:
return self.start_process("b10-cmdctl", args, self.c_channel_env,
self.cmdctl_port)
def start_xfrin(self):
# Set up the command arguments.
args = ['b10-xfrin']
if self.verbose:
args += ['-v']
return self.start_process("b10-xfrin", args, self.__ld_path_hack())
def start_xfrout(self):
# Set up the command arguments.
args = ['b10-xfrout']
if self.verbose:
args += ['-v']
return self.start_process("b10-xfrout", args, self.__ld_path_hack())
def start_all_components(self):
"""
Starts up all the components. Any exception generated during the
......@@ -812,6 +794,209 @@ class BoB: