Commit 144e8021 authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

Merge branch 'master' into trac2062

parents a64cb609 1170780a
451. [bug] muks, jinmei
libdatasrc: the database-based data source now correctly returns
glue records on (not under) a zone cut, such as in the case where
the NS name of an NS record is identical to its owner name. (Note:
libdatasrc itself doesn't judge what kind of record type can be a
"glue"; it's the caller's responsibility.)
(Trac #1771, git 483f1075942965f0340291e7ff7dae7806df22af)
450. [func]* tomek
b10-dhcp4: DHCPv4 server component is now integrated into
BIND10 framework. It can be started from BIND10 (using bindctl)
......
......@@ -92,7 +92,7 @@
<title>Supported Platforms</title>
<para>
BIND 10 builds have been tested on (in no particular order)
Debian GNU/Linux 5 and unstable, Ubuntu 9.10, NetBSD 5,
Debian GNU/Linux 6 and unstable, Ubuntu 9.10, NetBSD 5,
Solaris 10 and 11, FreeBSD 7 and 8, CentOS Linux 5.3,
MacOS 10.6 and 10.7, and OpenBSD 5.1.
......@@ -105,7 +105,17 @@
</section>
<section id="required-software">
<title>Required Software</title>
<title>Required Software at Run-time</title>
<para>
Running BIND 10 uses various extra software which may
not be provided in some operating systems' default
installations nor standard packages collections. You may
need to install this required software separately.
(For the build requirements, also see
<xref linkend="build-requirements"/>.)
</para>
<para>
BIND 10 requires at least Python 3.1
(<ulink url="http://www.python.org/"/>).
......@@ -140,15 +150,6 @@
Python modules need to be built for the corresponding Python 3.
</para>
<!-- TODO: this will change ... -->
<note>
<para>
Some operating systems do not provide these dependencies
in their default installation nor standard packages
collections.
You may need to install them separately.
</para>
</note>
</section>
<section id="starting_stopping">
......@@ -808,8 +809,9 @@ as a dependency earlier -->
The <command>b10-cfgmgr</command> daemon is always needed by every
module, if only to send information about themselves somewhere,
but more importantly to ask about their own settings, and
about other modules. The <command>b10-sockcreator</command> will
allocate sockets for the rest of the system.
about other modules. The <command>b10-sockcreator</command> daemon
helps allocate Internet addresses and ports as needed for BIND 10
network services.
</para>
<para>
......@@ -840,23 +842,22 @@ as a dependency earlier -->
</section>
<section id="bind10.config">
<title>Configuration of started processes</title>
<para>
The processes to be started can be configured, with the exception
of the <command>b10-sockcreator</command>, <command>b10-msgq</command>
and <command>b10-cfgmgr</command>.
</para>
<title>Configuration to start processes</title>
<para>
The configuration is in the Boss/components section. Each element
represents one component, which is an abstraction of a process
(currently there's also one component which doesn't represent
a process).
The processes to be used can be configured for
<command>bind10</command> to start, with the exception
of the required <command>b10-sockcreator</command>,
<command>b10-msgq</command> and <command>b10-cfgmgr</command>
components.
The configuration is in the <varname>Boss/components</varname>
section. Each element represents one component, which is
an abstraction of a process.
</para>
<para>
To add a process to the set, let's say the resolver (which not started
by default), you would do this:
To add a process to the set, let's say the resolver (which
is not started by default), you would do this:
<screen>&gt; <userinput>config add Boss/components b10-resolver</userinput>
&gt; <userinput>config set Boss/components/b10-resolver/special resolver</userinput>
&gt; <userinput>config set Boss/components/b10-resolver/kind needed</userinput>
......@@ -864,17 +865,21 @@ as a dependency earlier -->
&gt; <userinput>config commit</userinput></screen></para>
<para>
Now, what it means. We add an entry called b10-resolver. It is both a
name used to reference this component in the configuration and the
name of the process to start. Then we set some parameters on how to
start it.
Now, what it means. We add an entry called
<quote>b10-resolver</quote>. It is both a name used to
reference this component in the configuration and the name
of the process to start. Then we set some parameters on
how to start it.
</para>
<para>
The special one is for components that need some kind of special care
during startup or shutdown. Unless specified, the component is started
in usual way. This is the list of components that need to be started
in a special way, with the value of special used for them:
The <varname>special</varname> setting is for components
that need some kind of special care during startup or
shutdown. Unless specified, the component is started in a
usual way. This is the list of components that need to be
started in a special way, with the value of special used
for them:
<!-- TODO: this still doesn't explain why they are special -->
<table>
<title>Special startup components</title>
<tgroup cols='3' align='left'>
......@@ -883,9 +888,9 @@ as a dependency earlier -->
<colspec colname='description'/>
<thead><row><entry>Component</entry><entry>Special</entry><entry>Description</entry></row></thead>
<tbody>
<row><entry>b10-auth</entry><entry>auth</entry><entry>Authoritative server</entry></row>
<row><entry>b10-resolver</entry><entry>resolver</entry><entry>The resolver</entry></row>
<row><entry>b10-cmdctl</entry><entry>cmdctl</entry><entry>The command control (remote control interface)</entry></row>
<row><entry>b10-auth</entry><entry>auth</entry><entry>Authoritative DNS server</entry></row>
<row><entry>b10-resolver</entry><entry>resolver</entry><entry>DNS resolver</entry></row>
<row><entry>b10-cmdctl</entry><entry>cmdctl</entry><entry>Command control (remote control interface)</entry></row>
<!-- TODO Either add xfrin and xfrout as well or clean up the workarounds in boss before the release -->
</tbody>
</tgroup>
......@@ -893,32 +898,34 @@ as a dependency earlier -->
</para>
<para>
The kind specifies how a failure of the component should
be handled. If it is set to <quote>dispensable</quote>
(the default unless you set something else), it will get
started again if it fails. If it is set to <quote>needed</quote>
and it fails at startup, the whole <command>bind10</command>
shuts down and exits with error exit code. But if it fails
some time later, it is just started again. If you set it
to <quote>core</quote>, you indicate that the system is
not usable without the component and if such component
fails, the system shuts down no matter when the failure
happened. This is the behaviour of the core components
(the ones you can't turn off), but you can declare any
other components as core as well if you wish (but you can
turn these off, they just can't fail).
The <varname>kind</varname> specifies how a failure of the
component should be handled. If it is set to
<quote>dispensable</quote> (the default unless you set
something else), it will get started again if it fails. If
it is set to <quote>needed</quote> and it fails at startup,
the whole <command>bind10</command> shuts down and exits
with an error exit code. But if it fails some time later, it
is just started again. If you set it to <quote>core</quote>,
you indicate that the system is not usable without the
component and if such component fails, the system shuts
down no matter when the failure happened. This is the
behaviour of the core components (the ones you can't turn
off), but you can declare any other components as core as
well if you wish (but you can turn these off, they just
can't fail).
</para>
<para>
The priority defines order in which the components should start.
The ones with higher number are started sooner than the ones with
lower ones. If you don't set it, 0 (zero) is used as the priority.
Usually, leaving it at the default is enough.
The <varname>priority</varname> defines order in which the
components should start. The ones with higher numbers are
started sooner than the ones with lower ones. If you don't
set it, 0 (zero) is used as the priority. Usually, leaving
it at the default is enough.
</para>
<para>
There are other parameters we didn't use in our example.
One of them is <quote>address</quote>. It is the address
One of them is <varname>address</varname>. It is the address
used by the component on the <command>b10-msgq</command>
message bus. The special components already know their
address, but the usual ones don't. The address is by
......@@ -934,23 +941,15 @@ address, but the usual ones don't." mean? -->
<!-- TODO: document params when is enabled -->
<para>
The last one is process. It is the name of the process to be started.
It defaults to the name of the component if not set, but you can use
this to override it.
The last one is <varname>process</varname>. It is the name
of the process to be started. It defaults to the name of
the component if not set, but you can use this to override
it. (The special components also already know their
executable name.)
</para>
<!-- TODO Add parameters when they work, not implemented yet-->
<note>
<para>
This system allows you to start the same component multiple times
(by including it in the configuration with different names, but the
same process setting). However, the rest of the system doesn't expect
such a situation, so it would probably not do what you want. Such
support is yet to be implemented.
</para>
</note>
<note>
<para>
The configuration is quite powerful, but that includes
......@@ -972,7 +971,7 @@ address, but the usual ones don't." mean? -->
</note>
<para>
It is possible to start some components multiple times (currently
<command>b10-auth</command> and <command>b10-resolzer</command>).
<command>b10-auth</command> and <command>b10-resolver</command>).
You might want to do that to gain more performance (each one uses only
single core). Just put multiple entries under different names, like
this, with the same config:
......@@ -987,6 +986,9 @@ address, but the usual ones don't." mean? -->
server will keep its own copy of in-memory data and there could be
problems with locking the sqlite database, if used. The configuration
might be changed to something more convenient in future.
Other components don't expect such a situation, so it would
probably not do what you want. Such support is yet to be
implemented.
</para>
</section>
......@@ -1011,23 +1013,11 @@ address, but the usual ones don't." mean? -->
<para>
Administrators do not communicate directly with the
<command>b10-msgq</command> daemon.
By default, BIND 10 uses port 9912 for the
<command>b10-msgq</command> service.
It listens on 127.0.0.1.
By default, BIND 10 uses a UNIX domain socket file named
<filename>/usr/local/var/bind10-devel/msg_socket</filename>
for this interprocess communication.
</para>
<!-- TODO: this is broken, see Trac #111
<para>
To select an alternate port for the <command>b10-msgq</command> to
use, run <command>bind10</command> specifying the option:
<screen> $ <userinput>bind10 -TODO-msgq-port 9912</userinput></screen>
</para>
-->
<!-- TODO: upcoming plans:
Unix domain sockets
-->
</chapter>
<chapter id="cfgmgr">
......@@ -1069,9 +1059,6 @@ Unix domain sockets
specifications and all current settings to the
<command>bindctl</command> client (via
<command>b10-cmdctl</command>).
</para>
<para>
<command>b10-cfgmgr</command> relays configurations received
from <command>b10-cmdctl</command> to the appropriate modules.
</para>
......@@ -1090,7 +1077,7 @@ config changes are actually commands to cfgmgr
<para>
The stored configuration file is at
<filename>/usr/local/var/bind10-devel/b10-config.db</filename>.
(The full path is what was defined at build configure time for
(The directory is what was defined at build configure time for
<option>--localstatedir</option>.
The default is <filename>/usr/local/var/</filename>.)
The format is loosely based on JSON and is directly parseable
......@@ -1208,7 +1195,7 @@ but you might wanna check with likun
<!-- TODO
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
but that is a single file, maybethis should go back to that format?
but that is a single file, maybe this should go back to that format?
-->
<!--
......@@ -1275,7 +1262,6 @@ shutdown
<!--
TODO
(12:21:30) jinmei: I'd like to have sample session using a command line www client such as wget
(12:21:33) jinmei: btw
-->
</chapter>
......
......@@ -110,6 +110,9 @@ look into the cause and address the issue. The log message includes
the client's address (and port), and the error message sent from the
lower layer that detects the failure.
% AUTH_RECEIVED_NOTIFY received incoming NOTIFY for zone name %1, zone class %2
This is a debug message reporting that an incoming NOTIFY was received.
% AUTH_NOTIFY_QUESTIONS invalid number of questions (%1) in incoming NOTIFY
This debug message is logged by the authoritative server when it receives
a NOTIFY packet that contains zero or more than one question. (A valid
......
......@@ -828,6 +828,9 @@ AuthSrvImpl::processNotify(const IOMessage& io_message, Message& message,
return (false);
}
LOG_DEBUG(auth_logger, DBG_AUTH_DETAIL, AUTH_RECEIVED_NOTIFY)
.arg(question->getName()).arg(question->getClass());
const string remote_ip_address =
io_message.getRemoteEndpoint().getAddress().toText();
static const string command_template_start =
......
......@@ -541,7 +541,7 @@ class SecureHTTPServer(socketserver_mixin.NoPollMixIn,
ssl_version = ssl.PROTOCOL_SSLv23)
return ssl_sock
except (ssl.SSLError, CmdctlException) as err :
logger.info(CMDCTL_SSL_SETUP_FAILURE_USER_DENIED, err)
logger.error(CMDCTL_SSL_SETUP_FAILURE_USER_DENIED, err)
self.close_request(sock)
# raise socket error to finish the request
raise socket.error
......
......@@ -20,7 +20,7 @@
<refentry>
<refentryinfo>
<date>August 4, 2010</date>
<date>June 25, 2012</date>
</refentryinfo>
<refmeta>
......@@ -91,10 +91,6 @@
</itemizedlist>
</para>
<para>
It listens on 127.0.0.1.
</para>
<para>
The <command>b10-msgq</command> daemon may be cleanly stopped by
sending the SIGTERM signal to the process.
......@@ -168,5 +164,3 @@
- End:
-->
......@@ -889,6 +889,10 @@ class XfrinConnection(asyncore.dispatcher):
req_str = 'IXFR' if request_type == RRType.IXFR() else 'AXFR'
if check_soa:
self._check_soa_serial()
self.close()
self.init_socket()
if not self.connect_to_master():
raise XfrinException('Unable to reconnect to master')
logger.info(XFRIN_XFR_TRANSFER_STARTED, req_str, self.zone_str())
self._send_query(self._request_type)
......
......@@ -952,6 +952,9 @@ class XfroutServer:
def _start_notifier(self):
datasrc = self._unix_socket_server.get_db_file()
self._notifier = notify_out.NotifyOut(datasrc)
if 'also_notify' in self._config_data:
for slave in self._config_data['also_notify']:
self._notifier.add_slave(slave['address'], slave['port'])
self._notifier.dispatcher()
def send_notify(self, zone_name, zone_class):
......
......@@ -20,6 +20,33 @@
"item_optional": true
}
},
{
"item_name": "also_notify",
"item_type": "list",
"item_optional": true,
"item_default": [],
"list_item_spec":
{
"item_name": "also_notify_element",
"item_type": "map",
"item_optional": true,
"item_default": {},
"map_item_spec": [
{
"item_name": "address",
"item_type": "string",
"item_optional": false,
"item_default": ""
},
{
"item_name": "port",
"item_type": "integer",
"item_optional": false,
"item_default": 0
}
]
}
},
{
"item_name": "zone_config",
"item_type": "list",
......
......@@ -33,7 +33,6 @@ using namespace isc::data;
using namespace isc::config;
using namespace isc::cc;
using namespace std;
using namespace boost;
namespace {
std::string
......@@ -52,6 +51,7 @@ protected:
root_name(isc::log::getRootLoggerName())
{
// upon creation of a ModuleCCSession, the class
// sends its specification to the config manager.
// it expects an ok answer back, so everytime we
// create a ModuleCCSession, we must set an initial
......@@ -740,8 +740,9 @@ protected:
registerCommand(const string& recipient)
{
return (mccs_.groupRecvMsgAsync(
bind(&AsyncReceiveCCSessionTest::callback, this, next_flag_ ++, _1,
_2, _3), false, -1, recipient));
boost::bind(&AsyncReceiveCCSessionTest::callback, this,
next_flag_++, _1, _2, _3), false, -1,
recipient));
}
/// \brief Convenience function to queue a request to get a reply
/// message.
......@@ -749,8 +750,8 @@ protected:
registerReply(int seq)
{
return (mccs_.groupRecvMsgAsync(
bind(&AsyncReceiveCCSessionTest::callback, this, next_flag_ ++, _1,
_2, _3), true, seq));
boost::bind(&AsyncReceiveCCSessionTest::callback, this,
next_flag_++, _1, _2, _3), true, seq));
}
/// \brief Check the next called callback was with this flag
void called(int flag) {
......
......@@ -179,8 +179,7 @@ private:
DatabaseClient::Finder::FoundRRsets
DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
bool check_ns, const string* construct_name,
bool any,
const string* construct_name, bool any,
DatabaseAccessor::IteratorContextPtr context)
{
RRsigStore sig_store;
......@@ -204,9 +203,7 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
const Name construct_name_object(*construct_name);
bool seen_cname(false);
bool seen_ds(false);
bool seen_other(false);
bool seen_ns(false);
while (context->getNext(columns)) {
// The domain is not empty
......@@ -249,16 +246,12 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
if (cur_type == RRType::CNAME()) {
seen_cname = true;
} else if (cur_type == RRType::NS()) {
seen_ns = true;
} else if (cur_type == RRType::DS()) {
seen_ds = true;
} else if (cur_type != RRType::RRSIG() &&
cur_type != RRType::NSEC3() &&
cur_type != RRType::NSEC()) {
// NSEC and RRSIG can coexist with anything, otherwise
// we've seen something that can't live together with potential
// CNAME or NS
// CNAME.
//
// NSEC3 lives in separate namespace from everything, therefore
// we just ignore it here for these checks as well.
......@@ -278,14 +271,10 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
RDATA_COLUMN]);
}
}
if (seen_cname && (seen_other || seen_ns || seen_ds)) {
if (seen_cname && seen_other) {
isc_throw(DataSourceError, "CNAME shares domain " << name <<
" with something else");
}
if (check_ns && seen_ns && seen_other) {
isc_throw(DataSourceError, "NS shares domain " << name <<
" with something else");
}
// Add signatures to all found RRsets
for (std::map<RRType, RRsetPtr>::iterator i(result.begin());
i != result.end(); ++ i) {
......@@ -455,20 +444,20 @@ DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
for (int i = remove_labels; i > 0; --i) {
const Name superdomain(name.split(i));
// Note if this is the origin. (We don't count NS records at the origin
// as a delegation so this controls whether NS RRs are included in
// the results of some searches.)
const bool not_origin = (i != remove_labels);
// Look if there's NS or DNAME at this point of the tree, but ignore
// the NS RRs at the apex of the zone.
const FoundRRsets found = getRRsets(superdomain.toText(),
DELEGATION_TYPES(), not_origin);
DELEGATION_TYPES());
if (found.first) {
// This node contains either NS or DNAME RRs so it does exist.
const FoundIterator nsi(found.second.find(RRType::NS()));
const FoundIterator dni(found.second.find(RRType::DNAME()));
// Note if this is the origin. (We don't count NS records at the
// origin as a delegation so this controls whether NS RRs are
// included in the results of some searches.)
const bool not_origin = (i != remove_labels);
// An optimisation. We know that there is an exact match for
// something at this point in the tree so remember it. If we have
// to do a wildcard search, as we search upwards through the tree
......@@ -477,7 +466,7 @@ DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
last_known = superdomain.getLabelCount();
if (glue_ok && !first_ns && not_origin &&
nsi != found.second.end()) {
nsi != found.second.end()) {
// If we are searching for glue ("glue OK" mode), store the
// highest NS record that we find that is not the apex. This
// is another optimisation for later, where we need the
......@@ -590,8 +579,9 @@ DatabaseClient::Finder::findWildcardMatch(
// TODO Add a check for DNAME, as DNAME wildcards are discouraged (see
// RFC 4592 section 4.4).
// Search for a match. The types are the same as with original query.
FoundRRsets found = getRRsets(wildcard, final_types, true,
&construct_name, type == RRType::ANY());
const FoundRRsets found = getRRsets(wildcard, final_types,
&construct_name,
type == RRType::ANY());
if (found.first) {
// Found something - but what?
......@@ -694,7 +684,7 @@ DatabaseClient::Finder::FindDNSSECContext::probe() {
// such cases).
const string origin = finder_.getOrigin().toText();
const FoundRRsets nsec3_found =
finder_.getRRsets(origin, NSEC3PARAM_TYPES(), false);
finder_.getRRsets(origin, NSEC3PARAM_TYPES());
const FoundIterator nfi=
nsec3_found.second.find(RRType::NSEC3PARAM());
is_nsec3_ = (nfi != nsec3_found.second.end());
......@@ -705,7 +695,7 @@ DatabaseClient::Finder::FindDNSSECContext::probe() {
// described in Section 10.4 of RFC 5155.
if (!is_nsec3_) {
const FoundRRsets nsec_found =
finder_.getRRsets(origin, NSEC_TYPES(), false);
finder_.getRRsets(origin, NSEC_TYPES());
const FoundIterator nfi =
nsec_found.second.find(RRType::NSEC());
is_nsec_ = (nfi != nsec_found.second.end());
......@@ -757,10 +747,8 @@ DatabaseClient::Finder::FindDNSSECContext::getDNSSECRRset(const Name &name,
try {
const Name& nsec_name =
covering ? finder_.findPreviousName(name) : name;
const bool need_nscheck = (nsec_name != finder_.getOrigin());
const FoundRRsets found = finder_.getRRsets(nsec_name.toText(),
NSEC_TYPES(),
need_nscheck);
NSEC_TYPES());
const FoundIterator nci = found.second.find(RRType::NSEC());
if (nci != found.second.end()) {
return (nci->second);
......@@ -984,16 +972,15 @@ DatabaseClient::Finder::findInternal(const Name& name, const RRType& type,
// - Requested name is a delegation point (NS only but not at the zone
// apex - DNAME is ignored here as it redirects DNS names subordinate to
// the owner name - the owner name itself is not redirected.)
const bool is_origin = (name == getOrigin());
WantedTypes final_types(FINAL_TYPES());
final_types.insert(type);
const FoundRRsets found = getRRsets(name.toText(), final_types,
!is_origin, NULL,
type == RRType::ANY());
NULL, type == RRType::ANY());
FindDNSSECContext dnssec_ctx(*this, options);
if (found.first) {
// Something found at the domain name. Look into it further to get
// the final result.
const bool is_origin = (name == getOrigin());
return (findOnNameResult(name, type, options, is_origin, found, NULL,
target, dnssec_ctx));
} else {
......@@ -1021,7 +1008,7 @@ DatabaseClient::Finder::findNSEC3(const Name& name, bool recursive) {
// Now, we need to get the NSEC3 params from the apex and create the hash
// creator for it.
const FoundRRsets nsec3param(getRRsets(getOrigin().toText(),
NSEC3PARAM_TYPES(), false));
NSEC3PARAM_TYPES()));
const FoundIterator param(nsec3param.second.find(RRType::NSEC3PARAM()));
if (!nsec3param.first || param == nsec3param.second.end()) {
// No NSEC3 params? :-(
......@@ -1061,7 +1048,7 @@ DatabaseClient::Finder::findNSEC3(const Name& name, bool recursive) {
}
const FoundRRsets nsec3(getRRsets(hash + "." + otext, NSEC3_TYPES(),
false, NULL, false, context));
NULL, false, context));
if (nsec3.first) {
// We found an exact match against the current label.
......@@ -1086,8 +1073,8 @@ DatabaseClient::Finder::findNSEC3(const Name& name, bool recursive) {
arg(labels).arg(prevHash);
context = accessor_->getNSEC3Records(prevHash, zone_id_);
const FoundRRsets prev_nsec3(getRRsets(prevHash + "." + otext,
NSEC3_TYPES(), false, NULL,
false, context));
NSEC3_TYPES(), NULL, false,
context));
if (!prev_nsec3.first) {
isc_throw(DataSourceError, "Hash " + prevHash + " returned "
......