-// Copyright (C) 2012-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// client rather than a query for each subnet within this shared network.
// The only case when it is going to be less efficient is when there are
// more host identifier types in use than subnets within a shared network.
+ // As it breaks RADIUS and host caching this can be disabled by the
+ // host manager.
const bool use_single_query = network &&
+ !HostMgr::instance().getPreventCollection() &&
(network->getAllSubnets()->size() > ctx.host_identifiers_.size());
if (use_single_query) {
// client rather than a query for each subnet within this shared network.
// The only case when it is going to be less efficient is when there are
// more host identifier types in use than subnets within a shared network.
+ // As it breaks RADIUS and host caching this can be disabled by the
+ // host manager.
const bool use_single_query = network &&
+ !HostMgr::instance().getPreventCollection() &&
(network->getAllSubnets()->size() > ctx.host_identifiers_.size());
if (use_single_query) {
negative_caching_ = negative_caching;
}
+ /// @brief Returns the prevent collection flag.
+ ///
+ /// @return the prevent collection flag.
+ bool getPreventCollection() const {
+ return (prevent_collection_);
+ }
+
+ /// @brief Sets the prevent collection flag.
+ ///
+ void setPreventCollection(bool prevent_collection) {
+ prevent_collection_ = prevent_collection;
+ }
+
protected:
/// @brief The negative caching flag.
///
/// This works for get[46] for a subnet and an identifier.
bool negative_caching_;
+ /// @brief The prevent collection flag.
+ ///
+ /// When true prevent the use of lookup methods returning a
+ /// collection when methods returning a single object are usable instead.
+ bool prevent_collection_;
+
/// @brief Cache an answer.
///
/// @param host Pointer to the missied host.
private:
/// @brief Private default constructor.
- HostMgr() : negative_caching_(false) { }
+ HostMgr() : negative_caching_(false), prevent_collection_(false) { }
/// @brief List of alternate host data sources.
HostDataSourceList alternate_sources_;
-// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#include <config.h>
#include <dhcp/pkt4.h>
#include <dhcpsrv/shared_network.h>
+#include <dhcpsrv/host_mgr.h>
#include <dhcpsrv/tests/alloc_engine_utils.h>
#include <dhcpsrv/tests/test_utils.h>
#include <hooks/hooks_manager.h>
EXPECT_EQ("10.2.3.23", lease->addr_.toText());
}
+// Test that reservations within shared network take precedence over the
+// existing leases regardless in which subnet belonging to a shared network
+// reservations belong. Host lookups returning a collection are disabled.
+TEST_F(SharedNetworkAlloc4Test, discoverSharedNetworkReservationsNoColl) {
+
+ // Disable host lookups returning a collection.
+ ASSERT_FALSE(HostMgr::instance().getPreventCollection());
+ HostMgr::instance().setPreventCollection(true);
+
+ // Create reservation for the client.
+ HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
+ Host::IDENT_HWADDR, subnet2_->getID(),
+ SUBNET_ID_UNUSED, IOAddress("10.2.3.23")));
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
+ CfgMgr::instance().commit();
+
+ // Start allocation from subnet1. The engine should determine that the
+ // client has reservations in subnet2 and should rather assign reserved
+ // addresses.
+ AllocEngine::ClientContext4
+ ctx(subnet1_, ClientIdPtr(), hwaddr_, IOAddress::IPV4_ZERO_ADDRESS(),
+ false, false, "host.example.com.", true);
+ ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
+ AllocEngine::findReservation(ctx);
+ Lease4Ptr lease = engine_.allocateLease4(ctx);
+ ASSERT_TRUE(lease);
+ EXPECT_EQ("10.2.3.23", lease->addr_.toText());
+
+ // Let's create a lease for the client to make sure the lease is not
+ // renewed but a reserved lease is offerred.
+ Lease4Ptr lease2(new Lease4(IOAddress("192.0.2.17"), hwaddr_, ClientIdPtr(),
+ 501, 502, 503, time(NULL), subnet1_->getID()));
+ lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
+ ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease2));
+ ctx.subnet_ = subnet1_;
+ AllocEngine::findReservation(ctx);
+ lease = engine_.allocateLease4(ctx);
+ ASSERT_TRUE(lease);
+ EXPECT_EQ("10.2.3.23", lease->addr_.toText());
+}
+
// This test verifies that the server can offer an address from a shared
// subnet if there's at least 1 address left there, but will not offer
// anything if both subnets are completely full.
EXPECT_EQ("10.2.3.23", lease->addr_.toText());
}
+// Test that reservations within shared network take precedence over the
+// existing leases regardless in which subnet belonging to a shared network
+// reservations belong (DHCPREQUEST case). Host lookups returning a collection
+// are disabled.
+TEST_F(SharedNetworkAlloc4Test, requestSharedNetworkReservationsNoColl) {
+
+ // Disable host lookups returning a collection.
+ ASSERT_FALSE(HostMgr::instance().getPreventCollection());
+ HostMgr::instance().setPreventCollection(true);
+
+ // Create reservation for the client.
+ HostPtr host(new Host(&hwaddr_->hwaddr_[0], hwaddr_->hwaddr_.size(),
+ Host::IDENT_HWADDR, subnet2_->getID(),
+ SUBNET_ID_UNUSED, IOAddress("10.2.3.23")));
+ CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
+ CfgMgr::instance().commit();
+
+ // Start allocation from subnet1. The engine should determine that the
+ // client has reservations in subnet2 and should rather assign reserved
+ // addresses.
+ AllocEngine::ClientContext4
+ ctx(subnet1_, ClientIdPtr(), hwaddr_, IOAddress::IPV4_ZERO_ADDRESS(),
+ false, false, "host.example.com.", false);
+ ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+ AllocEngine::findReservation(ctx);
+ Lease4Ptr lease = engine_.allocateLease4(ctx);
+ ASSERT_TRUE(lease);
+ EXPECT_EQ("10.2.3.23", lease->addr_.toText());
+
+ // Remove the lease for another test below.
+ ASSERT_TRUE(LeaseMgrFactory::instance().deleteLease(lease->addr_));
+
+ // Let's create a lease for the client to make sure the lease is not
+ // renewed but a reserved lease is allocated again.
+ Lease4Ptr lease2(new Lease4(IOAddress("192.0.2.17"), hwaddr_, ClientIdPtr(),
+ 501, 502, 503, time(NULL), subnet1_->getID()));
+ lease->cltt_ = time(NULL) - 10; // Allocated 10 seconds ago
+ ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease2));
+ ctx.subnet_ = subnet1_;
+ AllocEngine::findReservation(ctx);
+ lease = engine_.allocateLease4(ctx);
+ ASSERT_TRUE(lease);
+ EXPECT_EQ("10.2.3.23", lease->addr_.toText());
+}
+
// This test checks if an expired lease can be reused in DHCPDISCOVER (fake
// allocation)
TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
-// Copyright (C) 2015-2018 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
#include <config.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
+#include <dhcpsrv/host_mgr.h>
#include <dhcpsrv/tests/alloc_engine_utils.h>
#include <dhcpsrv/tests/test_utils.h>
#include <stats/stats_mgr.h>
ASSERT_EQ("2001:db8:2::15", lease->addr_.toText());
}
+// This test verifies that the client is offerred a reserved address
+// even if this address belongs to another subnet within the same
+// shared network. Host lookups returning a collection are disabled.
+TEST_F(SharedNetworkAlloc6Test, solicitSharedNetworkReservationsNoColl) {
+ // Disable host lookups returning a collection.
+ ASSERT_FALSE(HostMgr::instance().getPreventCollection());
+ HostMgr::instance().setPreventCollection(true);
+
+ // Create reservation for the client in the second subnet.
+ subnet_ = subnet2_;
+ createHost6(true, IPv6Resrv::TYPE_NA, IOAddress("2001:db8:2::15"), 128);
+
+ // Start allocation from subnet1_. The engine should determine that the
+ // client has reservations in subnet2_ and should rather assign reserved
+ // addresses.
+ Pkt6Ptr query(new Pkt6(DHCPV6_SOLICIT, 1234));
+ AllocEngine::ClientContext6 ctx(subnet1_, duid_, false, false, "", true,
+ query);
+ ctx.currentIA().iaid_ = iaid_;
+
+ // Find reservations for this subnet/shared network.
+ AllocEngine::findReservation(ctx);
+
+ Lease6Ptr lease;
+ ASSERT_NO_THROW(lease = expectOneLease(engine_.allocateLeases6(ctx)));
+ ASSERT_TRUE(lease);
+ ASSERT_EQ("2001:db8:2::15", lease->addr_.toText());
+}
+
// This test verifies that the client is allocated a reserved address
// even if this address belongs to another subnet within the same
// shared network.
ASSERT_EQ("2001:db8:2::15", lease->addr_.toText());
}
+// This test verifies that the client is allocated a reserved address
+// even if this address belongs to another subnet within the same
+// shared network. Host lookups returning a collection are disabled.
+TEST_F(SharedNetworkAlloc6Test, requestSharedNetworkReservationsNoColl) {
+ // Disable host lookups returning a collection.
+ ASSERT_FALSE(HostMgr::instance().getPreventCollection());
+ HostMgr::instance().setPreventCollection(true);
+
+ // Create reservation for the client in the second subnet.
+ subnet_ = subnet2_;
+ createHost6(true, IPv6Resrv::TYPE_NA, IOAddress("2001:db8:2::15"), 128);
+
+ // Start allocation from subnet1_. The engine should determine that the
+ // client has reservations in subnet2_ and should rather assign reserved
+ // addresses.
+ Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
+ AllocEngine::ClientContext6 ctx(subnet1_, duid_, false, false, "", false,
+ query);
+ ctx.currentIA().iaid_ = iaid_;
+
+ // Find reservations for this subnet/shared network.
+ AllocEngine::findReservation(ctx);
+
+ Lease6Ptr lease;
+ ASSERT_NO_THROW(lease = expectOneLease(engine_.allocateLeases6(ctx)));
+ ASSERT_TRUE(lease);
+ ASSERT_EQ("2001:db8:2::15", lease->addr_.toText());
+}
+
// This test verifies that client is assigned an existing lease from a
// shared network, regardless of the default subnet. It also verifies that
// the client is assigned a reserved address from a shared network which