Commit 4c538c51 authored by Jelte Jansen's avatar Jelte Jansen
Browse files

sync with trunk


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3838 e5f2f494-b856-4b98-b285-d166d9295462
parents 091781ff 23e6b6ec
......@@ -12,6 +12,17 @@
It has "listen_on" and "forward_addresses" options.
(Trac #389, r3448)
127. [bug] stephen
During normal operation process termination and resurrection messages
are now output regardless of the state of the verbose flag.
(Trac #229, svn r3828)
126. [func] stephen, vorner, ocean
The Nameserver Address Store (NSAS) component has been added. It takes
care of choosing an IP address of a nameserver when a zone needs to be
contacted.
(Trac #356, Trac #408, svn r3823)
bind10-devel-20101201 released on December 01, 2010
125. [func] jelte
......
......@@ -318,7 +318,7 @@ if test "${boost_include_path}" ; then
BOOST_INCLUDES="-I${boost_include_path}"
CPPFLAGS="$CPPFLAGS $BOOST_INCLUDES"
fi
AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp],,
AC_CHECK_HEADERS([boost/shared_ptr.hpp boost/foreach.hpp boost/interprocess/sync/interprocess_upgradable_mutex.hpp],,
AC_MSG_ERROR([Missing required header files.]))
CPPFLAGS="$CPPFLAGS_SAVES"
AC_SUBST(BOOST_INCLUDES)
......@@ -523,6 +523,8 @@ AC_CONFIG_FILES([Makefile
src/lib/log/Makefile
src/lib/testutils/Makefile
src/lib/testutils/testdata/Makefile
src/lib/nsas/Makefile
src/lib/nsas/tests/Makefile
])
AC_OUTPUT([src/bin/cfgmgr/b10-cfgmgr.py
src/bin/cfgmgr/tests/b10-cfgmgr_test.py
......
......@@ -568,7 +568,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/
INPUT = ../src/lib/cc ../src/lib/config ../src/lib/dns ../src/lib/exceptions ../src/lib/datasrc ../src/bin/auth ../src/lib/bench ../src/lib/log ../src/lib/asiolink/ ../src/lib/nsas
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -128,7 +128,7 @@
libraries, to build BIND 10 from source code.
</p></div><p>
Building from source code requires the Boost
build-time headers. At least Boost version 1.34 is required.
build-time headers. At least Boost version 1.35 is required.
</p><p>
......
......@@ -274,7 +274,7 @@ var/
<para>
Building from source code requires the Boost
build-time headers. At least Boost version 1.34 is required.
build-time headers. At least Boost version 1.35 is required.
<!-- TODO: we don't check for this version -->
<!-- NOTE: jreed has tested with 1.34, 1.38, and 1.41. -->
</para>
......
......@@ -627,27 +627,44 @@ class BoB:
raise
if pid == 0: break
if pid in self.processes:
# One of the processes we know about. Get information on it.
proc_info = self.processes.pop(pid)
proc_info.restart_schedule.set_run_stop_time()
self.dead_processes[proc_info.pid] = proc_info
if self.verbose:
sys.stdout.write("[bind10] Process %s (PID %d) died.\n" %
(proc_info.name, proc_info.pid))
if proc_info.name == "b10-msgq":
if self.verbose and self.runnable:
# Write out message, but only if in the running state:
# During startup and shutdown, these messages are handled
# elsewhere.
if self.runnable:
if exit_status is None:
sys.stdout.write(
"[bind10] Process %s (PID %d) died: exit status not available" %
(proc_info.name, proc_info.pid))
else:
sys.stdout.write(
"[bind10] Process %s (PID %d) terminated, exit status = %d\n" %
(proc_info.name, proc_info.pid, exit_status))
# Was it a special process?
if proc_info.name == "b10-msgq":
sys.stdout.write(
"[bind10] The b10-msgq process died, shutting down.\n")
self.runnable = False
self.runnable = False
else:
sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
def restart_processes(self):
"""Restart any dead processes.
Returns the time when the next process is ready to be restarted.
If the server is shutting down, returns 0.
If there are no processes, returns None.
The values returned can be safely passed into select() as the
timeout value."""
"""
Restart any dead processes:
* Returns the time when the next process is ready to be restarted.
* If the server is shutting down, returns 0.
* If there are no processes, returns None.
The values returned can be safely passed into select() as the
timeout value.
"""
next_restart = None
# if we're shutting down, then don't restart
if not self.runnable:
......@@ -664,13 +681,12 @@ class BoB:
else:
if self.verbose:
sys.stdout.write("[bind10] Resurrecting dead %s process...\n" %
proc_info.name)
proc_info.name)
try:
proc_info.respawn()
self.processes[proc_info.pid] = proc_info
if self.verbose:
sys.stdout.write("[bind10] Resurrected %s (PID %d)\n" %
(proc_info.name, proc_info.pid))
sys.stdout.write("[bind10] Resurrected %s (PID %d)\n" %
(proc_info.name, proc_info.pid))
except:
still_dead[proc_info.pid] = proc_info
# remember any processes that refuse to be resurrected
......
SUBDIRS = exceptions dns cc config datasrc python xfr bench log asiolink \
testutils
testutils nsas
......@@ -877,12 +877,32 @@ TEST_F(DataSrcTest, NSECZonecutOfNonsecureZone) {
EXPECT_TRUE(it->isLast());
}
TEST_F(DataSrcTest, RootDSQuery) {
// Test sending a DS query to root (nonsense, but it should survive)
TEST_F(DataSrcTest, RootDSQuery1) {
EXPECT_NO_THROW(createAndProcessQuery(Name("."), RRClass::IN(),
RRType::DS()));
headerCheck(msg, Rcode::REFUSED(), true, false, true, 0, 0, 0);
}
// The same, but when we have the root zone
// (which triggers rfc4035 section 3.1.4.1)
TEST_F(DataSrcTest, RootDSQuery2) {
// The message
msg.makeResponse();
msg.setOpcode(Opcode::QUERY());
msg.addQuestion(Question(Name("."), RRClass::IN(), RRType::DS()));
msg.setHeaderFlag(Message::HEADERFLAG_RD);
// Prepare the source
DataSrcPtr sql3_source = DataSrcPtr(new Sqlite3DataSrc);
ConstElementPtr sqlite_root = Element::fromJSON(
"{ \"database_file\": \"" TEST_DATA_DIR "/test-root.sqlite3\"}");
EXPECT_NO_THROW(sql3_source->init(sqlite_root));
// Make the query
EXPECT_NO_THROW(performQuery(*sql3_source, cache, msg));
headerCheck(msg, Rcode::NOERROR(), true, true, true, 0, 1, 0);
}
TEST_F(DataSrcTest, DSQueryFromCache) {
// explicitly enable hot spot cache
cache.setEnabled(true);
......
SUBDIRS = . tests
AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES)
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/dns -I$(top_builddir)/src/lib/dns
AM_CPPFLAGS += -I$(top_srcdir)/src/lib/nsas -I$(top_builddir)/src/lib/nsas
AM_CPPFLAGS += $(SQLITE_CFLAGS)
AM_CXXFLAGS = $(B10_CXXFLAGS)
if USE_GXX
# Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time.
# https://svn.boost.org/trac/boost/ticket/3477
AM_CXXFLAGS += -Wno-missing-field-initializers
endif
lib_LTLIBRARIES = libnsas.la
libnsas_la_SOURCES = address_entry.h address_entry.cc
libnsas_la_SOURCES += asiolink.h
libnsas_la_SOURCES += hash.cc hash.h
libnsas_la_SOURCES += hash_deleter.h
libnsas_la_SOURCES += hash_key.cc hash_key.h
libnsas_la_SOURCES += hash_table.h
libnsas_la_SOURCES += lru_list.h
libnsas_la_SOURCES += nameserver_address_store.cc nameserver_address_store.h
libnsas_la_SOURCES += nameserver_address.h nameserver_address.cc
libnsas_la_SOURCES += nameserver_entry.cc nameserver_entry.h
libnsas_la_SOURCES += nsas_entry_compare.h
libnsas_la_SOURCES += nsas_entry.h nsas_types.h
libnsas_la_SOURCES += zone_entry.cc zone_entry.h
libnsas_la_SOURCES += fetchable.h
libnsas_la_SOURCES += address_request_callback.h
libnsas_la_SOURCES += resolver_interface.h
libnsas_la_SOURCES += random_number_generator.h
CLEANFILES = *.gcno *.gcda
For an overview of the Nameserver Address Store, see the requirements and design
documents at http://bind10.isc.org/wiki/Resolver.
At the time of writing (19 October 2010), the file asiolink.h is present in this
directory only for the purposes of development. When the recursor's
asynchronous I/O code has been finished, this will be removed and the NSAS will
use the "real" code.
Long term:
* Make a mechanism the cache (which does not exist at the time of writing this
note) will be able to notify the NSAS that something has changed (address,
new nameserver, etc). Because the cache will have access to the data and
knows when it changes (it updates its structures), it is the best place. It
will be caching even data like authority and additional sections. It will
notify us somehow (we will need to tell it when).
The changes we need to know about is when set of nameservers or set of
addresses for a nameserver change and when a NS record or nameserver's A or
AAAA record is explicitly removed from the cache.
* Optimisation to pass max two outstanding queries on the network (but fetch
everything from cache right away). The first can be done by having number of
packets on the network, with max of 4 (each query are 2 of them, A and AAAA),
if it drops to 2, another one can be send.
* Add the cache cookies/contexts.
* Logging.
* Remove LRU from the nameserver entries, drop them when they are not
referenced by any zone entry. This will remove duplicates, keep the RTTs
longer and will provide access to everything that exists. This is
tricky, though, because we need to be thread safe. There seems to be
solution to use weak_ptr inside the hash_table instead of shared_ptr and
catch the exception inside get() (and getOrAdd) and delete the dead pointer.
* Better way to dispatch all calbacks in a list is needed. We take them out of
the list and dispatch them one by one. This is wrong because when an
exception happens inside the callback, we lose the ones not dispatched yet.
What should be done in this situation anyway? Putting them back? Will anybody
still call them? Taking them one by one?
Or recommend that if the result is really needed, that destruction of it
should be considered failure if it wasn't called yet? Make it the default
(eg. signal failure by destruction or call that function from destructor)?
* Make a zone entry hash table have multiple LRU lists, each one for part of the
slots. This will prevent locking contention while still keeping close to
the theoretical LRU behaviour (statistically, accesses to each of the part
should be as common as to others).
It might be a good idea to encapsulate the LRUs into the hash table directly
(or create a class holding both the hash table and the LRU lists).
// Copyright (C) 2010 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.
// $Id$
/// \file address_entry.cc
///
/// This file exists to define the single constant \c AddressEntry::UNREACHABLE,
/// equal to the value \c UINT32_MAX.
///
/// Ideally we could use \c UINT32_MAX directly in the header file, but this
/// constant is defined in \c stdint.h only if the macro \c __STDC_LIMIT_MACROS
/// is defined first. (This apparently is the C89 standard.) Defining the
/// macro in \c address_entry.h before including \c stdint.h doesn't work as
/// it is possible that in a source file, \c stdint.h will be included before
/// \c address_entry.h. In that case, the \c stdint.h include sentinel will
/// prevent \c stdint.h being included a second time and the value won't be
/// defined.
///
/// The easiest solution is the one presented here: declare the value as a
/// static class constant, and define it in this source file. As we can control
/// the order of include files, this ensures that the value is defined.
#define __STDC_LIMIT_MACROS
#include <stdint.h>
#include "address_entry.h"
namespace isc {
namespace nsas {
const uint32_t AddressEntry::UNREACHABLE = UINT32_MAX;
}
}
// Copyright (C) 2010 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.
// $Id$
#ifndef __ADDRESS_ENTRY_H
#define __ADDRESS_ENTRY_H
/// \brief Address Entry
///
/// Lightweight class that couples an address with a RTT and provides some
/// convenience methods for accessing and updating the information.
#include <stdint.h>
#include "asiolink.h"
namespace isc {
namespace nsas {
class AddressEntry {
public:
/// Creates an address entry given IOAddress entry and RTT
/// This is the only constructor; the default copy constructor and
/// assignment operator are valid for this object.
///
/// \param address Address object representing this address
/// \param rtt Initial round-trip time
AddressEntry(const asiolink::IOAddress& address, uint32_t rtt = 0) :
address_(address), rtt_(rtt), dead_until_(0)
{}
/// \return Address object
asiolink::IOAddress getAddress() const {
return address_;
}
/// \return Current round-trip time
uint32_t getRTT() {
if(dead_until_ != 0 && time(NULL) >= dead_until_){
dead_until_ = 0;
rtt_ = 1; //reset the rtt to a small value so it has an opportunity to be updated
}
return rtt_;
}
/// Set current RTT
///
/// \param rtt New RTT to be associated with this address
void setRTT(uint32_t rtt) {
if(rtt == UNREACHABLE){
dead_until_ = time(NULL) + 5*60;//Cache the unreachable server for 5 minutes (RFC2308 sec7.2)
}
rtt_ = rtt;
}
/// Mark address as unreachable.
void setUnreachable() {
setRTT(UNREACHABLE); // Largest long number is code for unreachable
}
/// Check if address is unreachable
///
/// \return true if the address is unreachable, false if not
bool isUnreachable() {
return (getRTT() == UNREACHABLE); // The getRTT() will check the cache time for unreachable server
}
/// \return true if the object is a V4 address
bool isV4() const {
return (address_.getFamily() == AF_INET);
}
/// \return true if the object is a V6 address
bool isV6() const {
return (address_.getFamily() == AF_INET6);
}
// Next element is defined public for testing
static const uint32_t UNREACHABLE; ///< RTT indicating unreachable address
private:
asiolink::IOAddress address_; ///< Address
uint32_t rtt_; ///< Round-trip time
time_t dead_until_; ///< Dead time for unreachable server
};
} // namespace dns
} // namespace isc
#endif // __ADDRESS_ENTRY_H
// Copyright (C) 2010 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.
// $Id$
#ifndef __ADDRESS_REQUEST_CALLBACK_H
#define __ADDRESS_REQUEST_CALLBACK_H
#include "asiolink.h"
#include "nameserver_address.h"
namespace isc {
namespace nsas {
/// \brief Callback When Address Obtained
///
/// This is the callback object used to return an address of a nameserver to a
/// caller. It (or a subclass of it) is passed to the NSAS when a request is
/// made for the address of a nameserver. When an address is available,
/// methods on the passed objects are called.
///
/// Note that there is no guarantee as to when the methods are called; they
/// could be called after the function call that made the address request has
/// returned the caller. Equally, the call could complete before that function
/// call returns. It is up to the caller to handle all cases.
///
/// In terms of use, a shared pointer to this object is passed to the NSAS.
/// The NSAS will store the object via a shared pointer and after the callback
/// will delete the pointer. Whether this results in the deletion of the
/// callback object is up to the caller - if the caller wants to retain it
/// they should keep the shared pointer.
class AddressRequestCallback {
public:
/// Default constructor, copy contructor and assignment operator
/// are implicitly present and are OK.
/// \brief Virtual Destructor
virtual ~AddressRequestCallback()
{}
/// \brief Success Callback
///
/// This method is used when an address has been retrieved for the request.
///
/// \param address Address to be used to access the nameserver.
virtual void success(const NameserverAddress& address) = 0;
/// \brief Unreachable
///
/// This method is called when a request is made for an address, but all
/// the addresses for the zone are marked as unreachable. This may be
/// due to the NS records being unobtainable, or the A records for known
/// nameservers being unobtainable.
virtual void unreachable() = 0;
};
} // namespace nsas
} // namespace isc
#endif // __ADDRESS_REQUEST_CALLBACK_H
// Copyright (C) 2010 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.
// $Id$
#ifndef __ASIOLINK_H
#define __ASIOLINK_H
#include <string>
#include <sys/socket.h>
namespace asiolink {
/// \brief IO Address Dummy Class
///
/// As part of ther recursor, Evan has written the asiolink.h file, which
/// encapsulates some of the boost::asio classes. Until these are checked
/// into trunk and merged with this branch, these dummy classes should fulfill
/// their function.
class IOAddress {
public:
/// \param address_str String representing the address
IOAddress(const std::string& address_str) : address_(address_str)
{}
/// \param Just a virtual destructor
virtual ~ IOAddress() { }
/// \return Textual representation of the address
std::string toText() const
{return address_;}
/// \return Address family of the address
virtual short getFamily() const {
return ((address_.find(".") != std::string::npos) ? AF_INET : AF_INET6);
}
/// \return true if two addresses are equal
bool equal(const IOAddress& address)
{return (toText() == address.toText());}
private:
std::string address_; ///< Address represented
};
} // namespace asiolink
#endif // __ASIOLINK_H
// Copyright (C) 2010 CZ NIC
//
// 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.
// $id$
#ifndef __FETCHABLE_H
#define __FETCHABLE_H
/**
* \file fetchable.h
* \short Interface of information that can be fetched.
*/
namespace isc {
namespace nsas {
/**
* \short Interface of information that can be fetched.
*
* This just holds a state of information that can be fetched from somewhere.
* No locking is performed, if it is desirable, it should be locked manually.
*/
class Fetchable {
public:
/// \short States the Fetchable object can be in.
enum State {
/// \short No one yet asked for the information.
NOT_ASKED,
/// \short The information is too old and should not be used.
EXPIRED,
/// \short The information is asked for but it did not arrive.
IN_PROGRESS,
/// \short It is not possible to get the information.
UNREACHABLE,
/// \short The information is already present.
READY
};
/// \short Constructors
//@{
/// This creates the Fetchable object in the given state.
Fetchable(State state = NOT_ASKED) :
state_(state)
{ }
//@}
/// \short Getter and setter of current state.
//@{
State getState() const { return state_; }
void setState(State state) { state_ = state; }
//@}
private:
State state_;
};
} // namespace nsas
} // namespace isc
#endif // __FETCHABLE_H
// Copyright (C) 2010 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