Commit 1b6096af authored by Marcin Siodelski's avatar Marcin Siodelski

[3562] Implemented storage class for Hosts.

parent adae5408
......@@ -44,7 +44,9 @@ lib_LTLIBRARIES = libkea-dhcpsrv.la
libkea_dhcpsrv_la_SOURCES =
libkea_dhcpsrv_la_SOURCES += addr_utilities.cc addr_utilities.h
libkea_dhcpsrv_la_SOURCES += alloc_engine.cc alloc_engine.h
libkea_dhcpsrv_la_SOURCES += callout_handle_store.h
libkea_dhcpsrv_la_SOURCES += base_host_data_source.h
libkea_dhcpsrv_la_SOURCES += callout_handle_store.
libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
libkea_dhcpsrv_la_SOURCES += cfg_iface.cc cfg_iface.h
libkea_dhcpsrv_la_SOURCES += cfg_option.cc cfg_option.h
libkea_dhcpsrv_la_SOURCES += cfg_option_def.cc cfg_option_def.h
......@@ -59,6 +61,7 @@ libkea_dhcpsrv_la_SOURCES += dhcpsrv_log.cc dhcpsrv_log.h
libkea_dhcpsrv_la_SOURCES += dhcp_config_parser.h
libkea_dhcpsrv_la_SOURCES += dhcp_parsers.cc dhcp_parsers.h
libkea_dhcpsrv_la_SOURCES += host.cc host.h
libkea_dhcpsrv_la_SOURCES += host_container.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
libkea_dhcpsrv_la_SOURCES += lease_mgr.cc lease_mgr.h
......
// Copyright (C) 2014 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.
#ifndef BASE_HOST_DATA_SOURCE_H
#define BASE_HOST_DATA_SOURCE_H
#include <asiolink/io_address.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/host.h>
#include <exceptions/exceptions.h>
namespace isc {
namespace dhcp {
/// @brief Exception thrown when the duplicate @c Host object is detected.
class DuplicateHost : public Exception {
public:
DuplicateHost(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Base interface for the classes implementing simple data source
/// for host reservations.
///
/// This abstract class defines an interface for the classes implementing
/// basic data source for host reservations. This interface allows for
/// adding new reservations (represented by @c Host objects) and retrieving
/// these reservations using various parameters such as HW address or DUID,
/// subnet identifier (either IPv4 or IPv6) or reserved IP address.
///
/// This interface DOES NOT specify the methods to manage existing
/// host reservations such as to remove one IPv6 reservation but leave
/// other reservations. It also lacks the methods used for preparing
/// the data to be added to the SQL database: commit, rollback etc.
/// Such methods are declared in other interfaces.
class BaseHostDataSource {
public:
/// @brief Default destructor implementation.
virtual ~BaseHostDataSource() {
}
/// @brief Return all hosts for the specified HW address or DUID.
///
/// This method returns all @c Host objects which represent reservations
/// for the specified HW address or DUID. Note, that this method may
/// return multiple reservations because a particular client may have
/// reservations in multiple subnets and the same client may be identified
/// by HW address or DUID. The server is unable to verify that the specific
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const = 0;
/// @brief Non-const version of the @c getAll const method.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of non-const @c Host objects.
virtual HostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) = 0;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const = 0;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @return Collection of @c Host objects.
virtual HostCollection
getAll4(const asiolink::IOAddress& address) = 0;
/// @brief Returns a host connected to the IPv4 subnet.
///
/// Implementations of this method should guard against the case when
/// mutliple instances of the @c Host are present, e.g. when two
/// @c Host objects are found, one for the DUID, another one for the
/// HW address. In such case, an implementation of this method
/// should throw an exception.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
virtual ConstHostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const = 0;
/// @brief Returns a host connected to the IPv4 subnet.
///
/// Implementations of this method should guard against the case when
/// mutliple instances of the @c Host are present, e.g. when two
/// @c Host objects are found, one for the DUID, another one for the
/// HW address. In such case, an implementation of this method
/// should throw an exception.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
virtual HostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) = 0;
/// @brief Returns a host connected to the IPv6 subnet.
///
/// Implementations of this method should guard against the case when
/// mutliple instances of the @c Host are present, e.g. when two
/// @c Host objects are found, one for the DUID, another one for the
/// HW address. In such case, an implementation of this method
/// should throw an exception.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) const = 0;
/// @brief Returns a host connected to the IPv6 subnet.
///
/// Implementations of this method should guard against the case when
/// mutliple instances of the @c Host are present, e.g. when two
/// @c Host objects are found, one for the DUID, another one for the
/// HW address. In such case, an implementation of this method
/// should throw an exception.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
virtual HostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) = 0;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @return Const @c Host object using a specified HW address or DUID.
virtual ConstHostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const = 0;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
virtual HostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) = 0;
/// @brief Adds a new host to the collection.
///
/// The implementations of this method should guard against duplicate
/// reservations for the same host, where possible. For example, when the
/// reservation for the same HW address and subnet id is added twice, the
/// implementation should throw an exception. Note, that usually it is
/// impossible to guard against adding duplicated host, where one instance
/// is identified by HW address, another one by DUID.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host) = 0;
};
}
}
#endif // BASE_HOST_DATA_SOURCE_H
// Copyright (C) 2014 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.
#include <dhcpsrv/cfg_hosts.h>
#include <exceptions/exceptions.h>
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
ConstHostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
ConstHostCollection collection;
getAllInternal<ConstHostCollection>(hwaddr, duid, collection);
return (collection);
}
HostCollection
CfgHosts::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) {
HostCollection collection;
getAllInternal<HostCollection>(hwaddr, duid, collection);
return (collection);
}
ConstHostCollection
CfgHosts::getAll4(const IOAddress&) const {
isc_throw(isc::NotImplemented, "getAll4(address) const is not implemented");
}
HostCollection
CfgHosts::getAll4(const IOAddress&) {
isc_throw(isc::NotImplemented, "getAll4(address) is not implemented");
}
template<typename Storage>
void
CfgHosts::getAllInternal(const std::vector<uint8_t>& identifier,
const Host::IdentifierType& identifier_type,
Storage& storage) const {
// Search for the Host using the identifier and identifier type as a
// composite key.
const HostContainerIndex0& idx = hosts_.get<0>();
std::pair<HostContainerIndex0::iterator, HostContainerIndex0::iterator> r =
idx.equal_range(boost::make_tuple(identifier, identifier_type));
// Append each Host object to the storage.
for (HostContainerIndex0::iterator host = r.first; host != r.second;
++host) {
storage.push_back(*host);
}
}
template<typename Storage>
void
CfgHosts::getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
Storage& storage) const {
// Get hosts using HW address.
if (hwaddr) {
getAllInternal<Storage>(hwaddr->hwaddr_, Host::IDENT_HWADDR, storage);
}
// Get hosts using DUID.
if (duid) {
getAllInternal<Storage>(duid->getDuid(), Host::IDENT_DUID, storage);
}
}
ConstHostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const {
// The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid));
}
HostPtr
CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) {
// The false value indicates that it is an IPv4 subnet.
return (getHostInternal(subnet_id, false, hwaddr, duid));
}
ConstHostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) const {
// The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid));
}
HostPtr
CfgHosts::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) {
// The true value indicates that it is an IPv6 subnet.
return (getHostInternal(subnet_id, true, hwaddr, duid));
}
ConstHostPtr
CfgHosts::get6(const IOAddress&, const uint8_t) const {
isc_throw(isc::NotImplemented,
"get6(prefix, len) const is not implemented");
}
HostPtr
CfgHosts::get6(const IOAddress&, const uint8_t) {
isc_throw(isc::NotImplemented, "get6(prefix, len) is not implemented");
}
HostPtr
CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6,
const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
// 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
// because one host presumably doesn't show up in many subnets.
HostCollection hosts;
getAllInternal<HostCollection>(hwaddr, duid, hosts);
HostPtr host;
// Iterate over the returned hosts and select those for which the
// subnet id matches.
for (HostCollection::const_iterator host_it = hosts.begin();
host_it != hosts.end(); ++host_it) {
// Check if this is IPv4 subnet or IPv6 subnet.
SubnetID host_subnet_id = subnet6 ? (*host_it)->getIPv6SubnetID() :
(*host_it)->getIPv4SubnetID();
if (subnet_id == host_subnet_id) {
// If this is the first occurrence of the host for this subnet,
// remember it. But, if we find that this is second @c Host object
// for the same client, it is a misconfiguration. Most likely,
// the administrator has specified one reservation for a HW
// address and another one for the DUID, which gives an ambiguous
// result, and we don't know which reservation we should choose.
// Therefore, throw an exception.
if (!host) {
host = *host_it;
} else {
isc_throw(DuplicateHost, "more than one reservation found"
" for the host belonging to the subnet with id '"
<< subnet_id << "' and using the HW address '"
<< (hwaddr ? hwaddr->toText(false) : "(null)")
<< "' and DUID '"
<< (duid ? duid->toText() : "(null)")
<< "'");
}
}
}
return (host);
}
void
CfgHosts::add(const HostPtr& host) {
/// @todo This may need to be sanity-checked. For example, a duplicate
/// should be rejected.
HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid();
// Check for duplicates for the specified IPv4 subnet.
if (get4(host->getIPv4SubnetID(), host->getHWAddress(), host->getDuid())) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
<< "' to the IPv4 subnet id '" << host->getIPv4SubnetID()
<< "' as this host has already been added");
// Checek for duplicates for the specified IPv6 subnet.
} else if (get6(host->getIPv6SubnetID(), host->getDuid(),
host->getHWAddress())) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
<< "' to the IPv6 subnet id '" << host->getIPv6SubnetID()
<< "' as this host has already been added");
}
// This is a new instance - add it.
hosts_.insert(host);
}
} // end of namespace isc::dhcp
} // end of namespace isc
// Copyright (C) 2014 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.
#ifndef CFG_HOSTS_H
#define CFG_HOSTS_H
#include <asiolink/io_address.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/base_host_data_source.h>
#include <dhcpsrv/host.h>
#include <dhcpsrv/host_container.h>
#include <dhcpsrv/subnet_id.h>
#include <vector>
namespace isc {
namespace dhcp {
/// @brief Represents the host reservations specified in the configuration file.
///
/// This class holds a collection of the host reservations (@c Host objects)
/// which can be retrieved using different search criteria.
///
/// In the typical case the reservations are searched using the client's MAC
/// address of DUID and a subnet that the client is connected to. The
/// reservations can be also retrieved using other parameters, such as reserved
/// IP address.
///
/// The reservations are added to this object by the configuration parsers,
/// when the new configuration is applied for the server. The reservations
/// are retrieved by the @c HostMgr class when the server is allocating or
/// renewing an address or prefix for the particular client.
class CfgHosts : public BaseHostDataSource {
public:
/// @brief Return all hosts for the specified HW address or DUID.
///
/// This method returns all @c Host objects which represent reservations
/// for the specified HW address or DUID. Note, that this method may
/// return multiple reservations because a particular client may have
/// reservations in multiple subnets and the same client may be identified
/// by HW address or DUID. The server is unable to verify that the specific
/// DUID and HW address belong to the same client, until the client sends
/// a DHCP message.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const;
/// @brief Non-const version of the @c getAll const method.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available, e.g. DHCPv4 client case.
///
/// @return Collection of non-const @c Host objects.
virtual HostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr());
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @throw isc::NotImplemented.
virtual ConstHostCollection
getAll4(const asiolink::IOAddress& address) const;
/// @brief Returns a collection of hosts using the specified IPv4 address.
///
/// This method may return multiple @c Host objects if they are connected
/// to different subnets.
///
/// @param address IPv4 address for which the @c Host object is searched.
///
/// @throw isc::NotImplemented
virtual HostCollection
getAll4(const asiolink::IOAddress& address);
/// @brief Returns a host connected to the IPv4 subnet.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual ConstHostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr()) const;
/// @brief Returns a host connected to the IPv4 subnet.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual HostPtr
get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid = DuidPtr());
/// @brief Returns a host connected to the IPv6 subnet.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual ConstHostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr()) const;
/// @brief Returns a host connected to the IPv6 subnet.
///
/// @param subnet_id Subnet identifier.
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid DUID or NULL if not available.
///
/// @return Non-const @c Host object using a specified HW address or DUID.
/// @throw isc::dhcp::DuplicateHost if more than one candidate host has
/// been found.
virtual HostPtr
get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr = HWAddrPtr());
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @throw isc::NotImplemented.
virtual ConstHostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// @param prefix IPv6 prefix for which the @c Host object is searched.
/// @param prefix_len IPv6 prefix length.
///
/// @throw isc::NotImplemented.
virtual HostPtr
get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len);
/// @brief Adds a new host to the collection.
///
/// @param host Pointer to the new @c Host object being added.
///
/// @throw DuplicateHost If a host for a particular HW address or DUID
/// has already been added to the IPv4 or IPv6 subnet.
virtual void add(const HostPtr& host);
private:
/// @brief Returns @c Host objects for the specific identifier and type.
///
/// This private method is called by the @c CfgHosts::getAllInternal
/// method which finds the @c Host objects using HW address or DUID.
/// The retrieved objects are appended to the @c storage container.
///
/// @param identifier Binary representation of the HW addres or DUID (or
/// other future identifier).
/// @param identifier_type The type of the supplied identifier.
/// @param [out] storage Container to which the retreived objects are
/// appended.
/// @tparam One of the @c ConstHostCollection of @c HostCollection.
template<typename Storage>
void getAllInternal(const std::vector<uint8_t>& identifier,
const Host::IdentifierType& identifier_type,
Storage& storage) const;
/// @brief Returns @c Host objects for the specified HW address or DUID.
///
/// This private method is called by the @c CfgHosts::getAll methods to
/// retrieve the @c Host objects using HW address or DUID. The retrieved
/// objects are appended to the @c storage container.
///
/// @param hwaddr HW address identifying a host.
/// @param duid DUID identifying a host.
/// @param [out] storage Container to which the retrieved objects are
/// appended.
/// @tparam One of the @c ConstHostCollection or @c HostCollection.
template<typename Storage>
void getAllInternal(const HWAddrPtr& hwaddr, const DuidPtr& duid,
Storage& storage) const;
/// @brief Returns @c Host object connected to a subnet.
///
/// This private method returns a pointer to the @c Host object identified
/// by the HW address or DUID and connected to an IPv4 or IPv6 subnet.
///
/// @param subnet_id IPv4 or IPv6 subnet identifier.
/// @param subnet6 A boolean flag which indicates if the subnet identifier
/// points to a IPv4 (if false) or IPv6 subnet (if true).
/// @param hwaddr HW address identifying a host.
/// @param duid DUID identifying a host.
///
/// @return Pointer to the found host, or NULL if no host found.
/// @throw isc::dhcp::DuplicateHost if method found more than one matching