Commit ac87e6ce authored by Marcin Siodelski's avatar Marcin Siodelski

[3699] Added trace messages to the CfgHosts class.

parent e366ba78
/dhcpsrv_messages.cc /dhcpsrv_messages.cc
/dhcpsrv_messages.h /dhcpsrv_messages.h
/hosts_messages.cc
/hosts_messages.h
/s-messages /s-messages
...@@ -35,19 +35,22 @@ EXTRA_DIST += parsers/host_reservation_parser.h ...@@ -35,19 +35,22 @@ EXTRA_DIST += parsers/host_reservation_parser.h
EXTRA_DIST += parsers/host_reservations_list_parser.h EXTRA_DIST += parsers/host_reservations_list_parser.h
# Define rule to build logging source files from message file # Define rule to build logging source files from message file
dhcpsrv_messages.h dhcpsrv_messages.cc: s-messages dhcpsrv_messages.h dhcpsrv_messages.cc hosts_messages.h hosts_messages.cc: s-messages
s-messages: dhcpsrv_messages.mes s-messages: dhcpsrv_messages.mes hosts_messages.mes
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/dhcpsrv_messages.mes $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/dhcpsrv_messages.mes
touch $@ touch $@
$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/hosts_messages.mes
touch $@
# Tell Automake that the dhcpsrv_messages.{cc,h} source files are created in the # Tell Automake that the {dhcpsrv,hosts}_messages.{cc,h} source files are created
# build process, so it must create these before doing anything else. Although # in the build process, so it must create these before doing anything else.
# they are a dependency of the library (so will be created from the message file # Although they are a dependency of the library (so will be created from the message
# anyway), there is no guarantee as to exactly _when_ in the build they will be # file anyway), there is no guarantee as to exactly _when_ in the build they will be
# created. As the .h file is included in other sources file (so must be # created. As the .h file is included in other sources file (so must be
# present when they are compiled), the safest option is to create it first. # present when they are compiled), the safest option is to create it first.
BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
BUILT_SOURCES += hosts_messages.h hosts_messages.cc
# Some versions of GCC warn about some versions of Boost regarding # Some versions of GCC warn about some versions of Boost regarding
# missing initializer for members in its posix_time. # missing initializer for members in its posix_time.
...@@ -56,7 +59,8 @@ BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc ...@@ -56,7 +59,8 @@ BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG) AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
# Make sure the generated files are deleted in a "clean" operation # Make sure the generated files are deleted in a "clean" operation
CLEANFILES = *.gcno *.gcda dhcpsrv_messages.h dhcpsrv_messages.cc s-messages CLEANFILES = *.gcno *.gcda dhcpsrv_messages.h dhcpsrv_messages.cc
CLEANFILES += hosts_messages.h hosts_messages.cc s-messages
# Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests. # Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests.
CLEANFILES += *.csv CLEANFILES += *.csv
...@@ -84,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h ...@@ -84,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += host.cc host.h libkea_dhcpsrv_la_SOURCES += host.cc host.h
libkea_dhcpsrv_la_SOURCES += host_container.h libkea_dhcpsrv_la_SOURCES += host_container.h
libkea_dhcpsrv_la_SOURCES += host_mgr.cc host_mgr.h libkea_dhcpsrv_la_SOURCES += host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES += hosts_log.cc hosts_log.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_file_loader.h libkea_dhcpsrv_la_SOURCES += lease_file_loader.h
...@@ -125,6 +130,7 @@ libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h ...@@ -125,6 +130,7 @@ libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h
nodist_libkea_dhcpsrv_la_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc nodist_libkea_dhcpsrv_la_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
nodist_libkea_dhcpsrv_la_SOURCES += hosts_messages.h hosts_messages.cc
libkea_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS) libkea_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS)
libkea_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES) libkea_dhcpsrv_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
...@@ -154,6 +160,7 @@ endif ...@@ -154,6 +160,7 @@ endif
# The message file should be in the distribution # The message file should be in the distribution
EXTRA_DIST += dhcpsrv_messages.mes EXTRA_DIST += dhcpsrv_messages.mes
EXTRA_DIST += hosts_messages.mes
# Distribute backend documentation # Distribute backend documentation
# Database schema creation script moved to src/bin/admin # Database schema creation script moved to src/bin/admin
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE. // PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/cfg_hosts.h> #include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/hosts_log.h>
#include <exceptions/exceptions.h> #include <exceptions/exceptions.h>
#include <ostream> #include <ostream>
...@@ -23,6 +24,8 @@ namespace dhcp { ...@@ -23,6 +24,8 @@ namespace dhcp {
ConstHostCollection ConstHostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const { CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
ConstHostCollection collection; ConstHostCollection collection;
getAllInternal<ConstHostCollection>(hwaddr, duid, collection); getAllInternal<ConstHostCollection>(hwaddr, duid, collection);
return (collection); return (collection);
...@@ -30,6 +33,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const { ...@@ -30,6 +33,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
HostCollection HostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) { CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
// Do not issue logging message here because it will be logged by
// the getAllInternal method.
HostCollection collection; HostCollection collection;
getAllInternal<HostCollection>(hwaddr, duid, collection); getAllInternal<HostCollection>(hwaddr, duid, collection);
return (collection); return (collection);
...@@ -37,6 +42,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) { ...@@ -37,6 +42,8 @@ CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
ConstHostCollection ConstHostCollection
CfgHosts::getAll4(const IOAddress& address) const { CfgHosts::getAll4(const IOAddress& address) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
ConstHostCollection collection; ConstHostCollection collection;
getAllInternal4<ConstHostCollection>(address, collection); getAllInternal4<ConstHostCollection>(address, collection);
return (collection); return (collection);
...@@ -44,6 +51,8 @@ CfgHosts::getAll4(const IOAddress& address) const { ...@@ -44,6 +51,8 @@ CfgHosts::getAll4(const IOAddress& address) const {
HostCollection HostCollection
CfgHosts::getAll4(const IOAddress& address) { CfgHosts::getAll4(const IOAddress& address) {
// Do not issue logging message here because it will be logged by
// the getAllInternal4 method.
HostCollection collection; HostCollection collection;
getAllInternal4<HostCollection>(address, collection); getAllInternal4<HostCollection>(address, collection);
return (collection); return (collection);
...@@ -51,6 +60,8 @@ CfgHosts::getAll4(const IOAddress& address) { ...@@ -51,6 +60,8 @@ CfgHosts::getAll4(const IOAddress& address) {
ConstHostCollection ConstHostCollection
CfgHosts::getAll6(const IOAddress& address) const { CfgHosts::getAll6(const IOAddress& address) const {
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
ConstHostCollection collection; ConstHostCollection collection;
getAllInternal6<ConstHostCollection>(address, collection); getAllInternal6<ConstHostCollection>(address, collection);
return (collection); return (collection);
...@@ -58,6 +69,8 @@ CfgHosts::getAll6(const IOAddress& address) const { ...@@ -58,6 +69,8 @@ CfgHosts::getAll6(const IOAddress& address) const {
HostCollection HostCollection
CfgHosts::getAll6(const IOAddress& address) { CfgHosts::getAll6(const IOAddress& address) {
// Do not issue logging message here because it will be logged by
// the getAllInternal6 method.
HostCollection collection; HostCollection collection;
getAllInternal6<HostCollection>(address, collection); getAllInternal6<HostCollection>(address, collection);
return (collection); return (collection);
...@@ -68,6 +81,8 @@ void ...@@ -68,6 +81,8 @@ void
CfgHosts::getAllInternal(const std::vector<uint8_t>& identifier, CfgHosts::getAllInternal(const std::vector<uint8_t>& identifier,
const Host::IdentifierType& identifier_type, const Host::IdentifierType& identifier_type,
Storage& storage) const { Storage& storage) const {
// HOST_RESRV_GET_ALL_IDENTIFIER
// Use the identifier and identifier type as a composite key. // Use the identifier and identifier type as a composite key.
const HostContainerIndex0& idx = hosts_.get<0>(); const HostContainerIndex0& idx = hosts_.get<0>();
boost::tuple<const std::vector<uint8_t>, const Host::IdentifierType> t = boost::tuple<const std::vector<uint8_t>, const Host::IdentifierType> t =
...@@ -84,6 +99,10 @@ template<typename Storage> ...@@ -84,6 +99,10 @@ template<typename Storage>
void void
CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid, CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
Storage& storage) const { Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_HWADDR_DUID)
.arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)")
.arg(duid ? duid->toText() : "(no-duid)");
// Get hosts using HW address. // Get hosts using HW address.
if (hwaddr) { if (hwaddr) {
getAllInternal<Storage>(hwaddr->hwaddr_, Host::IDENT_HWADDR, storage); getAllInternal<Storage>(hwaddr->hwaddr_, Host::IDENT_HWADDR, storage);
...@@ -97,6 +116,9 @@ CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid, ...@@ -97,6 +116,9 @@ CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
template<typename Storage> template<typename Storage>
void void
CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const { CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_ADDRESS4)
.arg(address.toText());
// Must not specify address other than IPv4. // Must not specify address other than IPv4.
if (!address.isV4()) { if (!address.isV4()) {
isc_throw(BadHostAddress, "must specify an IPv4 address when searching" isc_throw(BadHostAddress, "must specify an IPv4 address when searching"
...@@ -115,6 +137,9 @@ CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const { ...@@ -115,6 +137,9 @@ CfgHosts::getAllInternal4(const IOAddress& address, Storage& storage) const {
template<typename Storage> template<typename Storage>
void void
CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const { CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_ADDRESS6)
.arg(address.toText());
// Must not specify address other than IPv6. // Must not specify address other than IPv6.
if (!address.isV6()) { if (!address.isV6()) {
isc_throw(BadHostAddress, "must specify an IPv6 address when searching" isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
...@@ -134,6 +159,7 @@ CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const { ...@@ -134,6 +159,7 @@ CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const {
ConstHostPtr ConstHostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr, CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const { const DuidPtr& duid) const {
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet. // The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid)); return (getHostInternal(subnet_id, false, hwaddr, duid));
} }
...@@ -141,12 +167,16 @@ CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr, ...@@ -141,12 +167,16 @@ CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
HostPtr HostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr, CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) { const DuidPtr& duid) {
// Do not log here because getHostInternal logs.
// The false value indicates that it is an IPv4 subnet. // The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid)); return (getHostInternal(subnet_id, false, hwaddr, duid));
} }
ConstHostPtr ConstHostPtr
CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const { CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4)
.arg(subnet_id).arg(address.toText());
ConstHostCollection hosts = getAll4(address); ConstHostCollection hosts = getAll4(address);
for (ConstHostCollection::const_iterator host = hosts.begin(); for (ConstHostCollection::const_iterator host = hosts.begin();
host != hosts.end(); ++host) { host != hosts.end(); ++host) {
...@@ -161,6 +191,7 @@ CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const { ...@@ -161,6 +191,7 @@ CfgHosts::get4(const SubnetID& subnet_id, const IOAddress& address) const {
ConstHostPtr ConstHostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid, CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) const { const HWAddrPtr& hwaddr) const {
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet. // The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid)); return (getHostInternal(subnet_id, true, hwaddr, duid));
} }
...@@ -168,6 +199,7 @@ CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid, ...@@ -168,6 +199,7 @@ CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
HostPtr HostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid, CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) { const HWAddrPtr& hwaddr) {
// Do not log here because getHostInternal logs.
// The true value indicates that it is an IPv6 subnet. // The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid)); return (getHostInternal(subnet_id, true, hwaddr, duid));
} }
...@@ -186,12 +218,29 @@ CfgHosts::get6(const IOAddress&, const uint8_t) { ...@@ -186,12 +218,29 @@ CfgHosts::get6(const IOAddress&, const uint8_t) {
ConstHostPtr ConstHostPtr
CfgHosts::get6(const SubnetID& subnet_id, CfgHosts::get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const { const asiolink::IOAddress& address) const {
ConstHostCollection storage; // Do not log here because getHostInternal6 logs.
getAllInternal6(subnet_id, address, storage); return (getHostInternal6<ConstHostPtr, ConstHostCollection>(subnet_id, address));
}
HostPtr
CfgHosts::get6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) {
// Do not log here because getHostInternal6 logs.
return (getHostInternal6<HostPtr, HostCollection>(subnet_id, address));
}
template<typename ReturnType, typename Storage>
ReturnType
CfgHosts::getHostInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS6)
.arg(subnet_id).arg(address.toText());
Storage storage;
getAllInternal6<Storage>(subnet_id, address, storage);
switch (storage.size()) { switch (storage.size()) {
case 0: case 0:
return (ConstHostPtr()); return (HostPtr());
case 1: case 1:
return (*storage.begin()); return (*storage.begin());
default: default:
...@@ -200,6 +249,7 @@ CfgHosts::get6(const SubnetID& subnet_id, ...@@ -200,6 +249,7 @@ CfgHosts::get6(const SubnetID& subnet_id,
<< subnet_id << "' and using the address '" << subnet_id << "' and using the address '"
<< address.toText() << "'"); << address.toText() << "'");
} }
} }
template<typename Storage> template<typename Storage>
...@@ -207,6 +257,9 @@ void ...@@ -207,6 +257,9 @@ void
CfgHosts::getAllInternal6(const SubnetID& subnet_id, CfgHosts::getAllInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& address, const asiolink::IOAddress& address,
Storage& storage) const { Storage& storage) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6)
.arg(subnet_id).arg(address.toText());
// Must not specify address other than IPv6. // Must not specify address other than IPv6.
if (!address.isV6()) { if (!address.isV6()) {
isc_throw(BadHostAddress, "must specify an IPv6 address when searching" isc_throw(BadHostAddress, "must specify an IPv6 address when searching"
...@@ -227,26 +280,15 @@ CfgHosts::getAllInternal6(const SubnetID& subnet_id, ...@@ -227,26 +280,15 @@ CfgHosts::getAllInternal6(const SubnetID& subnet_id,
} }
} }
HostPtr
CfgHosts::get6(const SubnetID& subnet_id, const asiolink::IOAddress& address) {
HostCollection storage;
getAllInternal6<HostCollection>(subnet_id, address, storage);
switch (storage.size()) {
case 0:
return (HostPtr());
case 1:
return (*storage.begin());
default:
isc_throw(DuplicateHost, "more than one reservation found"
" for the host belonging to the subnet with id '"
<< subnet_id << "' and using the address '"
<< address.toText() << "'");
}
}
HostPtr HostPtr
CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6, CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
const HWAddrPtr& hwaddr, const DuidPtr& duid) const { const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID)
.arg(subnet6 ? "IPv6" : "IPv4")
.arg(subnet_id)
.arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)")
.arg(duid ? duid->toText() : "(no-duid)");
// Get all hosts for the HW address and DUID. This may return multiple hosts // Get all hosts for the HW address and DUID. This may return multiple hosts
// for different subnets, but the number of hosts returned should be low // for different subnets, but the number of hosts returned should be low
// because one host presumably doesn't show up in many subnets. // because one host presumably doesn't show up in many subnets.
...@@ -290,11 +332,15 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6, ...@@ -290,11 +332,15 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
void void
CfgHosts::add(const HostPtr& host) { CfgHosts::add(const HostPtr& host) {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_ADD_HOST)
.arg(host ? host->toText() : "(no-host)");
// Sanity check that the host is non-null. // Sanity check that the host is non-null.
if (!host) { if (!host) {
isc_throw(BadValue, "specified host object must not be NULL when it" isc_throw(BadValue, "specified host object must not be NULL when it"
" is added to the configuration"); " is added to the configuration");
} }
// At least one subnet ID must be non-zero // At least one subnet ID must be non-zero
if (host->getIPv4SubnetID() == 0 && host->getIPv6SubnetID() == 0) { if (host->getIPv4SubnetID() == 0 && host->getIPv6SubnetID() == 0) {
isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of" isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of"
...@@ -308,7 +354,6 @@ CfgHosts::add(const HostPtr& host) { ...@@ -308,7 +354,6 @@ CfgHosts::add(const HostPtr& host) {
void void
CfgHosts::add4(const HostPtr& host) { CfgHosts::add4(const HostPtr& host) {
/// @todo This may need further sanity checks. /// @todo This may need further sanity checks.
HWAddrPtr hwaddr = host->getHWAddress(); HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid(); DuidPtr duid = host->getDuid();
...@@ -316,7 +361,7 @@ CfgHosts::add4(const HostPtr& host) { ...@@ -316,7 +361,7 @@ CfgHosts::add4(const HostPtr& host) {
// There should be at least one resource reserved: hostname, IPv4 // There should be at least one resource reserved: hostname, IPv4
// address, IPv6 address or prefix. // address, IPv6 address or prefix.
if (host->getHostname().empty() && if (host->getHostname().empty() &&
(host->getIPv4Reservation() == IOAddress("0.0.0.0")) && (host->getIPv4Reservation().isV4Zero()) &&
(!host->hasIPv6Reservation())) { (!host->hasIPv6Reservation())) {
std::ostringstream s; std::ostringstream s;
if (hwaddr) { if (hwaddr) {
...@@ -357,7 +402,6 @@ CfgHosts::add4(const HostPtr& host) { ...@@ -357,7 +402,6 @@ CfgHosts::add4(const HostPtr& host) {
void void
CfgHosts::add6(const HostPtr& host) { CfgHosts::add6(const HostPtr& host) {
/// @todo This may need further sanity checks. /// @todo This may need further sanity checks.
HWAddrPtr hwaddr = host->getHWAddress(); HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid(); DuidPtr duid = host->getDuid();
......
...@@ -339,6 +339,23 @@ private: ...@@ -339,6 +339,23 @@ private:
const HWAddrPtr& hwaddr, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const; const DuidPtr& duid) const;
/// @brief Returns the @c Host object holding reservation for the IPv6
/// address and connected to the specific subnet.
///
/// This private method is called by the public @c get6 method variants.
///
/// @param subnet_id IPv6 subnet identifier.
/// @param address IPv6 address.
/// @tparam ReturnType One of @c HostPtr or @c ConstHostPtr
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching
/// @c Host object.
template<typename ReturnType, typename Storage>
ReturnType getHostInternal6(const SubnetID& subnet_id,
const asiolink::IOAddress& adddress) const;
/// @brief Adds a new host to the v4 collection. /// @brief Adds a new host to the v4 collection.
/// ///
/// This is an internal method called by public @ref add. /// This is an internal method called by public @ref add.
......
...@@ -268,5 +268,61 @@ Host::getIdentifierAsText() const { ...@@ -268,5 +268,61 @@ Host::getIdentifierAsText() const {
return (txt); return (txt);
} }
std::string
Host::toText() const {
std::ostringstream s;
// Add HW address or DUID.
s << getIdentifierAsText();
// Add IPv4 subnet id if exists (non-zero).
if (ipv4_subnet_id_) {
s << " ipv4_subnet_id=" << ipv4_subnet_id_;
}
// Add IPv6 subnet id if exists (non-zero).
if (ipv6_subnet_id_) {
s << " ipv6_subnet_id=" << ipv6_subnet_id_;
}
// Add hostname.
s << " hostname=" << (hostname_.empty() ? "(empty)" : hostname_);
// Add IPv4 reservation.
s << " ipv4_reservation=" << (ipv4_reservation_.isV4Zero() ? "(no)" :
ipv4_reservation_.toText());
if (ipv6_reservations_.empty()) {
s << " ipv6_reservations=(none)";
} else {
// Add all IPv6 reservations.
for (IPv6ResrvIterator resrv = ipv6_reservations_.begin();
resrv != ipv6_reservations_.end(); ++resrv) {
s << " ipv6_reservation"
<< std::distance(ipv6_reservations_.begin(), resrv)
<< "=" << resrv->second.toText();
}
}
// Add DHCPv4 client classes.
for (ClientClasses::const_iterator cclass = dhcp4_client_classes_.begin();
cclass != dhcp4_client_classes_.end(); ++cclass) {
s << " dhcp4_class"
<< std::distance(dhcp4_client_classes_.begin(), cclass)
<< "=" << *cclass;
}
// Add DHCPv6 client classes.
for (ClientClasses::const_iterator cclass = dhcp6_client_classes_.begin();
cclass != dhcp6_client_classes_.end(); ++cclass) {
s << " dhcp6_class"
<< std::distance(dhcp6_client_classes_.begin(), cclass)
<< "=" << *cclass;
}
return (s.str());
}
} // end of namespace isc::dhcp } // end of namespace isc::dhcp
} // end of namespace isc } // end of namespace isc
...@@ -417,6 +417,9 @@ public: ...@@ -417,6 +417,9 @@ public:
return (dhcp6_client_classes_); return (dhcp6_client_classes_);
} }
/// @brief Returns information about the host in the textual format.
std::string toText() const;
private: private:
/// @brief Adds new client class for DHCPv4 or DHCPv6. /// @brief Adds new client class for DHCPv4 or DHCPv6.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <dhcpsrv/cfg_hosts.h> #include <dhcpsrv/cfg_hosts.h>
#include <dhcpsrv/cfgmgr.h> #include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/host_mgr.h> #include <dhcpsrv/host_mgr.h>
#include <dhcpsrv/hosts_log.h>
namespace { namespace {
...@@ -83,6 +84,11 @@ HostMgr::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr, ...@@ -83,6 +84,11 @@ HostMgr::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const { const DuidPtr& duid) const {
ConstHostPtr host = getCfgHosts()->get4(subnet_id, hwaddr, duid); ConstHostPtr host = getCfgHosts()->get4(subnet_id, hwaddr, duid);
if (!host && alternate_source) { if (!host && alternate_source) {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_HWADDR_DUID)
.arg(subnet_id)
.arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)")
.arg(duid ? duid->toText() : "(duid)");
host = alternate_source->get4(subnet_id, hwaddr, duid); host = alternate_source->get4(subnet_id, hwaddr, duid);
} }
return (host); return (host);
...@@ -93,6 +99,10 @@ HostMgr::get4(const SubnetID& subnet_id, ...@@ -93,6 +99,10 @@ HostMgr::get4(const SubnetID& subnet_id,
const asiolink::IOAddress& address) const { const asiolink::IOAddress& address) const {
ConstHostPtr host = getCfgHosts()->get4(subnet_id, address); ConstHostPtr host = getCfgHosts()->get4(subnet_id, address);
if (!host && alternate_source) { if (!host && alternate_source) {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_ADDRESS4)
.arg(subnet_id)
.arg(address.toText());
host = alternate_source->get4(subnet_id, address); host = alternate_source->get4(subnet_id, address);
} }
return (host); return (host);
...@@ -104,6 +114,11 @@ HostMgr::get6(const SubnetID& subnet_id, const DuidPtr& duid, ...@@ -104,6 +114,11 @@ HostMgr::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) const { const HWAddrPtr& hwaddr) const {
ConstHostPtr host = getCfgHosts()->get6(subnet_id, duid, hwaddr); ConstHostPtr host = getCfgHosts()->get6(subnet_id, duid, hwaddr);
if (!host && alternate_source) { if (!host && alternate_source) {
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
HOSTS_MGR_ALTERNATE_GET6_SUBNET_ID_DUID_HWADDR)