Commit faac5e97 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3561'

parents abbe8b20 50fe3842
......@@ -88,6 +88,7 @@
* - @subpage libdhcpsrv
* - @subpage leasemgr
* - @subpage cfgmgr
* - @subpage hostmgr
* - @subpage optionsConfig
* - @subpage allocengine
* - @subpage libdhcp_ddns
......
......@@ -64,6 +64,7 @@ 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 += host_mgr.cc host_mgr.h
libkea_dhcpsrv_la_SOURCES += host_reservation_parser.cc host_reservation_parser.h
libkea_dhcpsrv_la_SOURCES += key_from_key.h
libkea_dhcpsrv_la_SOURCES += lease.cc lease.h
......@@ -87,6 +88,7 @@ libkea_dhcpsrv_la_SOURCES += subnet_id.h
libkea_dhcpsrv_la_SOURCES += subnet_selector.h
libkea_dhcpsrv_la_SOURCES += triplet.h
libkea_dhcpsrv_la_SOURCES += utils.h
libkea_dhcpsrv_la_SOURCES += writable_host_data_source.h
nodist_libkea_dhcpsrv_la_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
......
......@@ -76,22 +76,6 @@ public:
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) const = 0;
/// @brief Non-const version of the @c getAll const method.
///
/// Specifying both hardware address and DUID is allowed for this method
/// and results in returning all objects that are associated with hardware
/// address OR duid. For example: if one host is associated with the
/// specified hardware address and another host is associated with the
/// specified DUID, two hosts will be returned.
///
/// @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
......@@ -103,17 +87,6 @@ public:
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
......@@ -132,24 +105,6 @@ public:
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
......@@ -168,23 +123,6 @@ public:
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.
///
......@@ -195,15 +133,6 @@ public:
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
......
......@@ -165,12 +165,17 @@ CfgHosts::add(const HostPtr& host) {
isc_throw(BadValue, "specified host object must not be NULL when it"
" is added to the configuration");
}
/// @todo This may need further sanity checks. For example, a duplicate
/// should be rejected.
// At least one subnet ID must be non-zero
if (host->getIPv4SubnetID() == 0 && host->getIPv6SubnetID() == 0) {
isc_throw(BadValue, "must not use both IPv4 and IPv6 subnet ids of"
" 0 when adding new host reservation");
}
/// @todo This may need further sanity checks.
HWAddrPtr hwaddr = host->getHWAddress();
DuidPtr duid = host->getDuid();
// Check for duplicates for the specified IPv4 subnet.
if (get4(host->getIPv4SubnetID(), hwaddr, duid)) {
if ((host->getIPv4SubnetID() > 0) &&
get4(host->getIPv4SubnetID(), hwaddr, duid)) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
......@@ -178,7 +183,8 @@ CfgHosts::add(const HostPtr& host) {
<< "' as this host has already been added");
// Checek for duplicates for the specified IPv6 subnet.
} else if (get6(host->getIPv6SubnetID(), duid, hwaddr)) {
} else if (host->getIPv6SubnetID() &&
get6(host->getIPv6SubnetID(), duid, hwaddr)) {
isc_throw(DuplicateHost, "failed to add new host using the HW"
" address '" << (hwaddr ? hwaddr->toText(false) : "(null)")
<< " and DUID '" << (duid ? duid->toText() : "(null)")
......
......@@ -18,10 +18,10 @@
#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 <dhcpsrv/writable_host_data_source.h>
#include <boost/shared_ptr.hpp>
#include <vector>
......@@ -42,7 +42,7 @@ namespace dhcp {
/// 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 {
class CfgHosts : public WritableHostDataSource {
public:
/// @brief Return all hosts for the specified HW address or DUID.
......
// 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 <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/host_mgr.h>
namespace {
/// @brief Convenience function returning a pointer to the hosts configuration.
///
/// This function is called by the @c HostMgr methods requiring access to the
/// host reservations specified in the DHCP server configuration.
///
/// @return A pointer to the const hosts reservation configuration.
isc::dhcp::ConstCfgHostsPtr getCfgHosts() {
return (isc::dhcp::CfgMgr::instance().getCurrentCfg()->getCfgHosts());
}
} // end of anonymous namespace
namespace isc {
namespace dhcp {
using namespace isc::asiolink;
boost::scoped_ptr<HostMgr>&
HostMgr::getHostMgrPtr() {
static boost::scoped_ptr<HostMgr> host_mgr_ptr;
return (host_mgr_ptr);
}
void
HostMgr::create(const std::string&) {
getHostMgrPtr().reset(new HostMgr());
/// @todo Initialize alternate_source here, using the parameter.
/// For example: alternate_source.reset(new MysqlHostDataSource(access)).
}
HostMgr&
HostMgr::instance() {
boost::scoped_ptr<HostMgr>& host_mgr_ptr = getHostMgrPtr();
if (!host_mgr_ptr) {
create();
}
return (*host_mgr_ptr);
}
ConstHostCollection
HostMgr::getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid) const {
ConstHostCollection hosts = getCfgHosts()->getAll(hwaddr, duid);
if (alternate_source) {
ConstHostCollection hosts_plus = alternate_source->getAll(hwaddr, duid);
hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
}
return (hosts);
}
ConstHostCollection
HostMgr::getAll4(const IOAddress& address) const {
ConstHostCollection hosts = getCfgHosts()->getAll4(address);
if (alternate_source) {
ConstHostCollection hosts_plus = alternate_source->getAll4(address);
hosts.insert(hosts.end(), hosts_plus.begin(), hosts_plus.end());
}
return (hosts);
}
ConstHostPtr
HostMgr::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr,
const DuidPtr& duid) const {
ConstHostPtr host = getCfgHosts()->get4(subnet_id, hwaddr, duid);
if (!host && alternate_source) {
host = alternate_source->get4(subnet_id, hwaddr, duid);
}
return (host);
}
ConstHostPtr
HostMgr::get6(const SubnetID& subnet_id, const DuidPtr& duid,
const HWAddrPtr& hwaddr) const {
ConstHostPtr host = getCfgHosts()->get6(subnet_id, duid, hwaddr);
if (!host && alternate_source) {
host = alternate_source->get6(subnet_id, duid, hwaddr);
}
return (host);
}
ConstHostPtr
HostMgr::get6(const IOAddress& prefix, const uint8_t prefix_len) const {
ConstHostPtr host = getCfgHosts()->get6(prefix, prefix_len);
if (!host && alternate_source) {
host = alternate_source->get6(prefix, prefix_len);
}
return (host);
}
void
HostMgr::add(const HostPtr&) {
isc_throw(isc::NotImplemented, "HostMgr::add is not implemented");
}
} // end of isc::dhcp namespace
} // end of isc namespace
// 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 HOST_MGR_H
#define HOST_MGR_H
#include <boost/noncopyable.hpp>
#include <boost/scoped_ptr.hpp>
namespace isc {
namespace dhcp {
/// @brief Host Manager.
///
/// This is a singleton class which provides access to multiple sources of
/// information about static host reservations. These sources are also referred
/// to as host data sources. Each source derives (directly or indirectly) from
/// the @c BaseHostDataSource.
///
/// The @c HostMgr is a central point for providing information about the host
/// reservations. Internally, it relays the queries (calls to the appropriate
/// methods declared in the @c BaseHostDataSource) to the data sources it is
/// connected to. The @c HostMgr is always connected to the server's
/// configuration, accessible through the @c CfgHosts object in the @c CfgMgr.
/// The @c CfgHosts object holds all reservations specified in the DHCP server
/// configuration file. If a particular reservation is not found in the
/// @c CfgHosts object, the @c HostMgr will try to find it using the alternate
/// host data storage. The alternate host data storage is usually a database
/// (e.g. SQL database), accessible through a dedicated host data source
/// object (a.k.a. database backend). This datasource is responsible for
/// managing the connection with the database and forming appropriate queries
/// to retrieve (or update) the information about the reservations.
///
/// The use of the alternate host data source is optional and usually requires
/// additional configuration to be specified by the server administrator.
/// For example, for the SQL database the user's credentials, database address,
/// and database name are required. The @c HostMgr passes these parameters
/// to an appropriate datasource which is responsible for opening a connection
/// and maintaining it.
///
/// It is possible to switch to a different alternate data source or disable
/// the use of the alternate datasource, e.g. as a result of server's
/// reconfiguration. However, the use of the primary host data source (i.e.
/// reservations specified in the configuration file) can't be disabled.
///
/// @todo Implement alternate host data sources: MySQL, PostgreSQL, etc.
class HostMgr : public boost::noncopyable, BaseHostDataSource {
public:
/// @brief Creates new instance of the @c HostMgr.
///
/// If an instance of the @c HostMgr already exists, it will be replaced
/// by the new instance. Thus, any instances of the alternate host data
/// sources will be dropped.
///
/// @param access Host data source access parameters for the alternate
/// host data source. It holds "keyword=value" pairs, separated by spaces.
/// The supported values are specific to the alternate data source in use.
/// However, the "type" parameter will be common and it will specify which
/// data source is to be used. Currently, no parameters are supported
/// and the parameter is ignored.
static void create(const std::string& access = "");
/// @brief Returns a sole instance of the @c HostMgr.
///
/// This method should be used to retrieve an instance of the @c HostMgr
/// to be used to gather/manage host reservations. It returns an instance
/// of the @c HostMgr created by the @c create method. If such instance
/// doesn't exist yet, it is created using the @c create method with the
/// default value of the data access string, which configures the host
/// manager to not use the alternate host data source.
static HostMgr& instance();
/// @brief Returns all hosts for the specified HW address or DUID.
///
/// This method returns all @c Host objects representing reservations for
/// the specified HW address or/and DUID as documented in the
/// @c BaseHostDataSource::getAll.
///
/// It retrieves reservations from both primary and alternate host data
/// source as a single collection of @c Host objects, i.e. if matching
/// reservations are in both sources, all of them are returned.
///
/// Note that returned collection may contain duplicates. It is the
/// caller's responsibility to check for duplicates.
///
/// @param hwaddr HW address of the client or NULL if no HW address
/// available.
/// @param duid client id or NULL of not available.
///
/// @return Collection of const @c Host objects.
virtual ConstHostCollection
getAll(const HWAddrPtr& hwaddr, const DuidPtr& duid = DuidPtr()) 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.
///
/// If matching reservations are both in the primary and the alternate
/// data source, all of them are returned.
///
/// @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;
/// @brief Returns a host connected to the IPv4 subnet.
///
/// This method returns a single reservation for the particular host
/// (identified by the HW address or DUID) as documented in the
/// @c BaseHostDataSource::get4.
///
/// @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;
/// @brief Returns a host connected to the IPv6 subnet.
///
/// This method returns a host connected to the IPv6 subnet and identified
/// by the HW address or DUID, as described in the
/// @c BaseHostDataSource::get6.
///
/// @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;
/// @brief Returns a host using the specified IPv6 prefix.
///
/// This method returns a host using specified IPv6 prefix, as described
/// in the @c BaseHostDataSource::get6.
///
/// @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;
/// @brief Adds a new host to the alternate data source.
///
/// This method will throw an exception if no alternate data source is
/// in use.
///
/// @param host Pointer to the new @c Host object being added.
virtual void add(const HostPtr& host);
private:
/// @brief Private default constructor.
HostMgr() { }
/// @brief Pointer to an alternate host data source.
///
/// If this pointer is NULL, the source is not in use.
boost::scoped_ptr<BaseHostDataSource> alternate_source;
/// @brief Returns a pointer to the currently used instance of the
/// @c HostMgr.
static boost::scoped_ptr<HostMgr>& getHostMgrPtr();
};
}
}
#endif // HOST_MGR_H
......@@ -81,6 +81,39 @@ one that occurred before it etc.
the \ref isc::dhcp::SrvConfig object. Kea developers are actively working
on migrating the other configuration parameters to it.
@section hostmgr Host Manager
Host Manager implemented by the \ref isc::dhcp::HostMgr is a singleton object
which provides means to retrieve resources statically assigned to the DHCP
clients, such as IP addresses, prefixes or hostnames. The statically assigned
resources are called reservations (or host reservations) and they are
represented in the code by the \ref isc::dhcp::Host class.
The reservations can be specified in the configuration file or in some
other storage (typically in a database). A dedicated object, called
host data source, is needed to retrieve the host reservations from the
database. This object must implement the \ref isc::dhcp::BaseHostDataSource
interface and its implementation is specific to the type of storage
holding the reservations. For example, the host data source managing
host reservations in the MySQL database is required to establish
connection to the MySQL databse and issue specific queries. Once
implemented, the \ref isc::dhcp::HostMgr::create method must be updated
to create an instance of this datasource. Note, that this instance is
created as "alternate host data source" as opposed to the primary data
source which returns host reservations specified in the configuration file.
The primary data source is implemented internally in the
\ref isc::dhcp::HostMgr and uses the configuration data structures held by
the \ref isc::dhcp::CfgMgr to retrieve the reservations. In general, the
\ref isc::dhcp::HostMgr first searches for the reservations using the
primary data source and falls back to the use of alternate data source
when nothing has been found. For those methods which are meant to return
multiple reservations (e.g. find all reservations for the particular
client), the \ref isc::dhcp::HostMgr will use both primary and alternate
data source (if present) and concatenate results.
For more information about the \ref isc::dhcp::HostMgr please refer to its
documentation.
@section optionsConfig Options Configuration Information
The \ref isc::dhcp::CfgOption object holds a collection of options being
......@@ -117,7 +150,7 @@ that handles allocation of new leases. It takes parameters that the client
provided (client-id, DUID, subnet, a hint if the user provided one, etc.) and
then attempts to allocate a lease.
There is no single best soluction to the address assignment problem. Server
There is no single best solution to the address assignment problem. Server
is expected to pick an address from its available pools is currently not used.
There are many possible algorithms that can do that, each with its own advantages
and drawbacks. This allocation engine must provide robust operation is radically
......
......@@ -68,6 +68,7 @@ libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
libdhcpsrv_unittests_SOURCES += daemon_unittest.cc
libdhcpsrv_unittests_SOURCES += dbaccess_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += host_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += host_unittest.cc
libdhcpsrv_unittests_SOURCES += host_reservation_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += lease_file_io.cc lease_file_io.h
......
......@@ -99,11 +99,11 @@ TEST_F(CfgHostsTest, getAllNonRepeatingHosts) {
for (int i = 0; i < 25; ++i) {
cfg.add(HostPtr(new Host(hwaddrs_[i]->toText(false),
"hw-address",
SubnetID(i % 10), SubnetID(i % 5),
SubnetID(i % 10 + 1), SubnetID(i % 5 + 1),
IOAddress("192.0.2.5"))));
cfg.add(HostPtr(new Host(duids_[i]->toText(), "duid",
SubnetID(i % 5), SubnetID(i % 10),
SubnetID(i % 5 + 1), SubnetID(i % 10 + 1),
IOAddress("192.0.2.10"))));
}
......@@ -115,14 +115,14 @@ TEST_F(CfgHostsTest, getAllNonRepeatingHosts) {
// points to a host for which the reservation hasn't been added.
HostCollection hosts = cfg.getAll(hwaddrs_[i], duids_[i + 25]);
ASSERT_EQ(1, hosts.size());
EXPECT_EQ(i % 10, hosts[0]->getIPv4SubnetID());
EXPECT_EQ(i % 10 + 1, hosts[0]->getIPv4SubnetID());
EXPECT_EQ("192.0.2.5", hosts[0]->getIPv4Reservation().toText());
// Get host identified by DUID. The HW address is non-null but it
// points to a host for which the reservation hasn't been added.
hosts = cfg.getAll(hwaddrs_[i + 25], duids_[i]);
ASSERT_EQ(1, hosts.size());
EXPECT_EQ(i % 5, hosts[0]->getIPv4SubnetID());
EXPECT_EQ(i % 5 + 1, hosts[0]->getIPv4SubnetID());
EXPECT_EQ("192.0.2.10", hosts[0]->getIPv4Reservation().toText());
}
......@@ -292,6 +292,15 @@ TEST_F(CfgHostsTest, get6) {
EXPECT_THROW(cfg.get6(SubnetID(1), duids_[0], hwaddrs_[0]), DuplicateHost);
}
TEST_F(CfgHostsTest, zeroSubnetIDs) {
CfgHosts cfg;
ASSERT_THROW(cfg.add(HostPtr(new Host(hwaddrs_[0]->toText(false),
"hw-address",
SubnetID(0), SubnetID(0),
IOAddress("10.0.0.1")))),
isc::BadValue);
}
// This test verifies that it is not possible to add the same Host to the
// same IPv4 subnet twice.
TEST_F(CfgHostsTest, duplicatesSubnet4HWAddr) {
......@@ -299,21 +308,21 @@ TEST_F(CfgHostsTest, duplicatesSubnet4HWAddr) {
// Add a host.
ASSERT_NO_THROW(cfg.add(HostPtr(new Host(hwaddrs_[0]->toText(false),
"hw-address",
SubnetID(10), SubnetID(1),
SubnetID(10), SubnetID(0),
IOAddress("10.0.0.1")))));
// Try to add the host with the same HW address to the same subnet. The fact
// that the IP address is different here shouldn't really matter.
EXPECT_THROW(cfg.add(HostPtr(new Host(hwaddrs_[0]->toText(false),
"hw-address",
SubnetID(10), SubnetID(12),
SubnetID(10), SubnetID(0),
IOAddress("10.0.0.10")))),
isc::dhcp::DuplicateHost);
// Now try to add it to a different subnet. It should go through.
EXPECT_NO_THROW(cfg.add(HostPtr(new Host(hwaddrs_[0]->toText(false),
"hw-address",
SubnetID(11), SubnetID(12),
SubnetID(11), SubnetID(0),
IOAddress("10.0.0.10")))));
}
......@@ -324,21 +333,21 @@ TEST_F(CfgHostsTest, duplicatesSubnet4DUID) {
// Add a host.