2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-31 22:15:23 +00:00

[2995] 4 hook points implemented:

- pkt6_receive, subnet6_select, lease6_select, pkt6_send
 - framework updated
 - some unittests implemented
This commit is contained in:
Tomek Mrugalski
2013-06-21 19:26:54 +02:00
parent 7c20771f42
commit eff9543714
19 changed files with 434 additions and 27 deletions

View File

@@ -63,6 +63,7 @@ b10_dhcp4_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/libb10-log.la b10_dhcp4_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la b10_dhcp4_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la b10_dhcp4_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
b10_dhcp4_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
b10_dhcp4dir = $(pkgdatadir) b10_dhcp4dir = $(pkgdatadir)
b10_dhcp4_DATA = dhcp4.spec b10_dhcp4_DATA = dhcp4.spec

View File

@@ -71,6 +71,7 @@ dhcp4_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la dhcp4_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la dhcp4_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la dhcp4_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
endif endif
noinst_PROGRAMS = $(TESTS) noinst_PROGRAMS = $(TESTS)

View File

@@ -65,6 +65,7 @@ b10_dhcp6_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la b10_dhcp6_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/libb10-log.la b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/util/libb10-util.la b10_dhcp6_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
b10_dhcp6dir = $(pkgdatadir) b10_dhcp6dir = $(pkgdatadir)
b10_dhcp6_DATA = dhcp6.spec b10_dhcp6_DATA = dhcp6.spec

View File

@@ -38,6 +38,9 @@ const int DBG_DHCP6_COMMAND = DBGLVL_COMMAND;
// Trace basic operations within the code. // Trace basic operations within the code.
const int DBG_DHCP6_BASIC = DBGLVL_TRACE_BASIC; const int DBG_DHCP6_BASIC = DBGLVL_TRACE_BASIC;
// Trace hook related operations
const int DBG_DHCP6_HOOKS = DBGLVL_TRACE_BASIC;
// Trace detailed operations, including errors raised when processing invalid // Trace detailed operations, including errors raised when processing invalid
// packets. (These are not logged at severities of WARN or higher for fear // packets. (These are not logged at severities of WARN or higher for fear
// that a set of deliberately invalid packets set to the server could overwhelm // that a set of deliberately invalid packets set to the server could overwhelm

View File

@@ -65,6 +65,24 @@ This informational message is printed every time the IPv6 DHCP server
is started. It indicates what database backend type is being to store is started. It indicates what database backend type is being to store
lease and other information. lease and other information.
% DHCP6_HOOK_PACKET_RCVD_SKIP received DHCPv6 packet was dropped, because a callout set skip flag.
This debug message is printed when a callout installed on pkt6_received
hook point sets skip flag. This flag instructs the server to skip the next processing
stage, which would be to handle the packet. This effectively means drop the packet.
% DHCP6_HOOK_PACKET_SEND_SKIP Prepared DHCPv6 response was not sent, because a callout set skip flag.
This debug message is printed when a callout installed on pkt6_send
hook point sets skip flag. This flag instructs the server to skip the next processing
stage, which would be to send a response. This effectively means that the client will
not get any response, even though the server processed client's request and acted on
it (e.g. could possible allocate a lease).
% DHCP6_HOOK_SUBNET6_SELECT_SKIP No subnet was selected, because a callout set skip flag.
This debug message is printed when a callout installed on subnet6_select
hook point sets a skip flag. It means that the server was told that no subnet
should be selected. This severely limits further processing - server will be only
able to offer global options. No addresses or prefixes could be assigned.
% DHCP6_LEASE_ADVERT lease %1 advertised (client duid=%2, iaid=%3) % DHCP6_LEASE_ADVERT lease %1 advertised (client duid=%2, iaid=%3)
This debug message indicates that the server successfully advertised This debug message indicates that the server successfully advertised
a lease. It is up to the client to choose one server out of the a lease. It is up to the client to choose one server out of the

View File

@@ -37,6 +37,9 @@
#include <util/io_utilities.h> #include <util/io_utilities.h>
#include <util/range_utilities.h> #include <util/range_utilities.h>
#include <util/encode/hex.h> #include <util/encode/hex.h>
#include <hooks/server_hooks.h>
#include <hooks/hooks_manager.h>
#include <hooks/callout_handle.h>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/tokenizer.hpp> #include <boost/tokenizer.hpp>
@@ -50,6 +53,7 @@
using namespace isc; using namespace isc;
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::hooks;
using namespace isc::util; using namespace isc::util;
using namespace std; using namespace std;
@@ -67,7 +71,9 @@ namespace dhcp {
static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid"; static const char* SERVER_DUID_FILE = "b10-dhcp6-serverid";
Dhcpv6Srv::Dhcpv6Srv(uint16_t port) Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
: alloc_engine_(), serverid_(), shutdown_(true) { :alloc_engine_(), serverid_(), shutdown_(true), hook_index_pkt6_receive_(100),
hook_index_subnet6_select_(101), hook_index_pkt6_send_(102)
{
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_OPEN_SOCKET).arg(port); LOG_DEBUG(dhcp6_logger, DBG_DHCP6_START, DHCP6_OPEN_SOCKET).arg(port);
@@ -106,6 +112,15 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
// Instantiate allocation engine // Instantiate allocation engine
alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)); alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
// Register hook points
hook_index_pkt6_receive_ = ServerHooks::getServerHooks().registerHook("pkt6_receive");
hook_index_subnet6_select_ = ServerHooks::getServerHooks().registerHook("subnet6_select");
hook_index_pkt6_send_ = ServerHooks::getServerHooks().registerHook("pkt6_send");
/// @todo call loadLibraries() when handling configuration changes
vector<string> libraries; // no libraries at this time
HooksManager::getHooksManager().loadLibraries(libraries);
} catch (const std::exception &e) { } catch (const std::exception &e) {
LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what()); LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what());
return; return;
@@ -126,6 +141,10 @@ void Dhcpv6Srv::shutdown() {
shutdown_ = true; shutdown_ = true;
} }
Pkt6Ptr Dhcpv6Srv::receivePacket(int timeout) {
return (IfaceMgr::instance().receive6(timeout));
}
bool Dhcpv6Srv::run() { bool Dhcpv6Srv::run() {
while (!shutdown_) { while (!shutdown_) {
/// @todo: calculate actual timeout to the next event (e.g. lease /// @todo: calculate actual timeout to the next event (e.g. lease
@@ -134,14 +153,15 @@ bool Dhcpv6Srv::run() {
/// For now, we are just calling select for 1000 seconds. There /// For now, we are just calling select for 1000 seconds. There
/// were some issues reported on some systems when calling select() /// were some issues reported on some systems when calling select()
/// with too large values. Unfortunately, I don't recall the details. /// with too large values. Unfortunately, I don't recall the details.
int timeout = 1000; //cppcheck-suppress variableScope This is temporary anyway
const int timeout = 1000;
// client's message and server's response // client's message and server's response
Pkt6Ptr query; Pkt6Ptr query;
Pkt6Ptr rsp; Pkt6Ptr rsp;
try { try {
query = IfaceMgr::instance().receive6(timeout); query = receivePacket(timeout);
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG_ERROR(dhcp6_logger, DHCP6_PACKET_RECEIVE_FAIL).arg(e.what()); LOG_ERROR(dhcp6_logger, DHCP6_PACKET_RECEIVE_FAIL).arg(e.what());
} }
@@ -159,6 +179,24 @@ bool Dhcpv6Srv::run() {
.arg(query->getBuffer().getLength()) .arg(query->getBuffer().getLength())
.arg(query->toText()); .arg(query->toText());
// Let's execute all callouts registered for packet_received
if (HooksManager::getHooksManager().calloutsPresent(hook_index_pkt6_receive_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// This is the first callout, so no need to clear any arguments
callout_handle->setArgument("pkt6", query);
HooksManager::getHooksManager().callCallouts(hook_index_pkt6_receive_,
*callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to process the packet, so skip at this
// stage means drop.
if (callout_handle->getSkip()) {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_RCVD_SKIP);
continue;
}
}
try { try {
switch (query->getType()) { switch (query->getType()) {
case DHCPV6_SOLICIT: case DHCPV6_SOLICIT:
@@ -203,7 +241,7 @@ bool Dhcpv6Srv::run() {
} catch (const RFCViolation& e) { } catch (const RFCViolation& e) {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_REQUIRED_OPTIONS_CHECK_FAIL) LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_REQUIRED_OPTIONS_CHECK_FAIL)
.arg(query->getName()) .arg(query->getName())
.arg(query->getRemoteAddr()) .arg(query->getRemoteAddr().toText())
.arg(e.what()); .arg(e.what());
} catch (const isc::Exception& e) { } catch (const isc::Exception& e) {
@@ -217,7 +255,7 @@ bool Dhcpv6Srv::run() {
// packets.) // packets.)
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_PROCESS_FAIL) LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_PACKET_PROCESS_FAIL)
.arg(query->getName()) .arg(query->getName())
.arg(query->getRemoteAddr()) .arg(query->getRemoteAddr().toText())
.arg(e.what()); .arg(e.what());
} }
@@ -229,6 +267,32 @@ bool Dhcpv6Srv::run() {
rsp->setIndex(query->getIndex()); rsp->setIndex(query->getIndex());
rsp->setIface(query->getIface()); rsp->setIface(query->getIface());
// Execute all callouts registered for packet6_send
if (HooksManager::getHooksManager().calloutsPresent(hook_index_pkt6_send_)) {
boost::shared_ptr<CalloutHandle> callout_handle = getCalloutHandle(query);
// Delete all previous arguments
callout_handle->deleteAllArguments();
// Clear skip flag if it was set in previous callouts
callout_handle->setSkip(false);
// Set our response
callout_handle->setArgument("pkt6", rsp);
// Call all installed callouts
HooksManager::getHooksManager().callCallouts(hook_index_pkt6_send_,
*callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to send the packet, so skip at this
// stage means "drop response".
if (callout_handle->getSkip()) {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_PACKET_SEND_SKIP);
continue;
}
}
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA, LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL_DATA,
DHCP6_RESPONSE_DATA) DHCP6_RESPONSE_DATA)
.arg(static_cast<int>(rsp->getType())).arg(rsp->toText()); .arg(static_cast<int>(rsp->getType())).arg(rsp->toText());
@@ -559,6 +623,29 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) {
} }
} }
// Let's execute all callouts registered for packet_received
if (HooksManager::getHooksManager().calloutsPresent(hook_index_subnet6_select_)) {
boost::shared_ptr<CalloutHandle> callout_handle = getCalloutHandle(question);
// This is the first callout, so no need to clear any arguments
callout_handle->setArgument("pkt6", question);
callout_handle->setArgument("subnet6", subnet);
callout_handle->setArgument("subnet6collection", CfgMgr::instance().getSubnets6());
HooksManager::getHooksManager().callCallouts(hook_index_subnet6_select_,
*callout_handle);
// Callouts decided to skip this step. This means that no subnet will be
// selected. Packet processing will continue, but it will be severly limited
// (i.e. only global options will be assigned)
if (callout_handle->getSkip()) {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_SUBNET6_SELECT_SKIP);
return (Subnet6Ptr());
}
// Use whatever subnet was specified by the callout
callout_handle->getArgument("subnet6", subnet);
}
return (subnet); return (subnet);
} }
@@ -618,7 +705,8 @@ Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
switch (opt->second->getType()) { switch (opt->second->getType()) {
case D6O_IA_NA: { case D6O_IA_NA: {
OptionPtr answer_opt = assignIA_NA(subnet, duid, question, OptionPtr answer_opt = assignIA_NA(subnet, duid, question,
boost::dynamic_pointer_cast<Option6IA>(opt->second)); boost::dynamic_pointer_cast<Option6IA>(opt->second),
question);
if (answer_opt) { if (answer_opt) {
answer->addOption(answer_opt); answer->addOption(answer_opt);
} }
@@ -632,7 +720,7 @@ Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer) {
OptionPtr OptionPtr
Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid, Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
Pkt6Ptr question, boost::shared_ptr<Option6IA> ia) { Pkt6Ptr question, boost::shared_ptr<Option6IA> ia, const Pkt6Ptr& query) {
// If there is no subnet selected for handling this IA_NA, the only thing to do left is // If there is no subnet selected for handling this IA_NA, the only thing to do left is
// to say that we are sorry, but the user won't get an address. As a convenience, we // to say that we are sorry, but the user won't get an address. As a convenience, we
// use a different status text to indicate that (compare to the same status code, // use a different status text to indicate that (compare to the same status code,
@@ -676,12 +764,15 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
fake_allocation = true; fake_allocation = true;
} }
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Use allocation engine to pick a lease for this client. Allocation engine // Use allocation engine to pick a lease for this client. Allocation engine
// will try to honour the hint, but it is just a hint - some other address // will try to honour the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will // may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well. // be inserted into the LeaseMgr as well.
Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid, ia->getIAID(), Lease6Ptr lease = alloc_engine_->allocateAddress6(subnet, duid, ia->getIAID(),
hint, fake_allocation); hint, fake_allocation,
callout_handle);
// Create IA_NA that we will put in the response. // Create IA_NA that we will put in the response.
// Do not use OptionDefinition to create option's instance so // Do not use OptionDefinition to create option's instance so
@@ -1102,5 +1193,24 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& infRequest) {
return reply; return reply;
} }
isc::hooks::CalloutHandlePtr Dhcpv6Srv::getCalloutHandle(const Pkt6Ptr& pkt) {
CalloutHandlePtr callout_handle;
static Pkt6Ptr old_pointer;
if (!callout_handle ||
old_pointer != pkt) {
// This is the first packet or a different packet than previously
// passed to getCalloutHandle()
// Remember the pointer to this packet
old_pointer = pkt;
callout_handle = HooksManager::getHooksManager().createCalloutHandle();
}
return (callout_handle);
}
}; };
}; };

View File

@@ -23,6 +23,7 @@
#include <dhcp/pkt6.h> #include <dhcp/pkt6.h>
#include <dhcpsrv/alloc_engine.h> #include <dhcpsrv/alloc_engine.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <hooks/hooks_manager.h>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@@ -87,6 +88,20 @@ public:
/// @brief Instructs the server to shut down. /// @brief Instructs the server to shut down.
void shutdown(); void shutdown();
/// @brief returns ServerHooks object
/// @todo: remove this as soon as ServerHooks object is converted
/// to a signleton.
//static boost::shared_ptr<isc::util::ServerHooks> getServerHooks();
/// @brief returns Callout Manager object
///
/// This manager is used to manage callouts registered on various hook
/// points. @todo exact access method for HooksManager manager will change
/// when it will be converted to a singleton.
///
/// @return CalloutManager instance
//static boost::shared_ptr<isc::util::HooksManager> getHooksManager();
protected: protected:
/// @brief verifies if specified packet meets RFC requirements /// @brief verifies if specified packet meets RFC requirements
@@ -189,7 +204,8 @@ protected:
OptionPtr assignIA_NA(const isc::dhcp::Subnet6Ptr& subnet, OptionPtr assignIA_NA(const isc::dhcp::Subnet6Ptr& subnet,
const isc::dhcp::DuidPtr& duid, const isc::dhcp::DuidPtr& duid,
isc::dhcp::Pkt6Ptr question, isc::dhcp::Pkt6Ptr question,
boost::shared_ptr<Option6IA> ia); boost::shared_ptr<Option6IA> ia,
const Pkt6Ptr& query);
/// @brief Renews specific IA_NA option /// @brief Renews specific IA_NA option
/// ///
@@ -321,6 +337,13 @@ protected:
/// @return string representation /// @return string representation
static std::string duidToString(const OptionPtr& opt); static std::string duidToString(const OptionPtr& opt);
/// @brief dummy wrapper around IfaceMgr::receive6
///
/// This method is useful for testing purposes, where its replacement
/// simulates reception of a packet. For that purpose it is protected.
virtual Pkt6Ptr receivePacket(int timeout);
private: private:
/// @brief Allocation Engine. /// @brief Allocation Engine.
/// Pointer to the allocation engine that we are currently using /// Pointer to the allocation engine that we are currently using
@@ -334,6 +357,17 @@ private:
/// Indicates if shutdown is in progress. Setting it to true will /// Indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure. /// initiate server shutdown procedure.
volatile bool shutdown_; volatile bool shutdown_;
isc::hooks::CalloutHandlePtr getCalloutHandle(const Pkt6Ptr& pkt);
void packetProcessStart(const Pkt6Ptr& pkt);
void packetProcessEnd(const Pkt6Ptr& pkt);
/// Indexes for registered hook points
int hook_index_pkt6_receive_;
int hook_index_subnet6_select_;
int hook_index_pkt6_send_;
}; };
}; // namespace isc::dhcp }; // namespace isc::dhcp

View File

@@ -68,6 +68,7 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la dhcp6_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
endif endif
noinst_PROGRAMS = $(TESTS) noinst_PROGRAMS = $(TESTS)

View File

@@ -33,12 +33,16 @@
#include <util/buffer.h> #include <util/buffer.h>
#include <util/range_utilities.h> #include <util/range_utilities.h>
#include <hooks/server_hooks.h>
#include <hooks/callout_manager.h>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <unistd.h> #include <unistd.h>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <list>
using namespace isc; using namespace isc;
using namespace isc::asiolink; using namespace isc::asiolink;
@@ -46,6 +50,7 @@ using namespace isc::config;
using namespace isc::data; using namespace isc::data;
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::util; using namespace isc::util;
using namespace isc::hooks;
using namespace std; using namespace std;
// namespace has to be named, because friends are defined in Dhcpv6Srv class // namespace has to be named, because friends are defined in Dhcpv6Srv class
@@ -61,6 +66,26 @@ public:
LeaseMgrFactory::create(memfile); LeaseMgrFactory::create(memfile);
} }
virtual Pkt6Ptr receivePacket(int /*timeout*/) {
// If there is anything prepared as fake incoming
// traffic, use it
if (!to_be_received_.empty()) {
Pkt6Ptr pkt = to_be_received_.front();
to_be_received_.pop_front();
return (pkt);
}
// If not, just trigger shutdown and
// return immediately
shutdown();
return (Pkt6Ptr());
}
void fakeReceive(const Pkt6Ptr& pkt) {
to_be_received_.push_back(pkt);
}
virtual ~NakedDhcpv6Srv() { virtual ~NakedDhcpv6Srv() {
// Close the lease database // Close the lease database
LeaseMgrFactory::destroy(); LeaseMgrFactory::destroy();
@@ -75,6 +100,8 @@ public:
using Dhcpv6Srv::sanityCheck; using Dhcpv6Srv::sanityCheck;
using Dhcpv6Srv::loadServerID; using Dhcpv6Srv::loadServerID;
using Dhcpv6Srv::writeServerID; using Dhcpv6Srv::writeServerID;
list<Pkt6Ptr> to_be_received_;
}; };
static const char* DUID_FILE = "server-id-test.txt"; static const char* DUID_FILE = "server-id-test.txt";
@@ -226,6 +253,9 @@ public:
} }
virtual ~NakedDhcpv6SrvTest() { virtual ~NakedDhcpv6SrvTest() {
// Remove all registered hook points
ServerHooks::getServerHooks().reset();
// Let's clean up if there is such a file. // Let's clean up if there is such a file.
unlink(DUID_FILE); unlink(DUID_FILE);
}; };
@@ -1756,6 +1786,85 @@ TEST_F(Dhcpv6SrvTest, ServerID) {
EXPECT_EQ(duid1_text, text); EXPECT_EQ(duid1_text, text);
} }
// Checks if hooks are implemented properly.
TEST_F(Dhcpv6SrvTest, Hooks) {
NakedDhcpv6Srv srv(0);
// check if appropriate hooks are registered
// check if appropriate indexes are set
int hook_index_pkt6_received = ServerHooks::getServerHooks().getIndex("pkt6_receive");
int hook_index_select_subnet = ServerHooks::getServerHooks().getIndex("subnet6_select");
int hook_index_pkt6_send = ServerHooks::getServerHooks().getIndex("pkt6_send");
EXPECT_TRUE(hook_index_pkt6_received > 0);
EXPECT_TRUE(hook_index_select_subnet > 0);
EXPECT_TRUE(hook_index_pkt6_send > 0);
}
// This function returns buffer for empty packet (just DHCPv6 header)
Pkt6* captureEmpty() {
Pkt6* pkt;
uint8_t data[4];
data[0] = 1; // type 1 = SOLICIT
data[1] = 0xca; // trans-id = 0xcafe01
data[2] = 0xfe;
data[3] = 0x01;
pkt = new Pkt6(data, sizeof(data));
pkt->setRemotePort(546);
pkt->setRemoteAddr(IOAddress("fe80::1"));
pkt->setLocalPort(0);
pkt->setLocalAddr(IOAddress("ff02::1:2"));
pkt->setIndex(2);
pkt->setIface("eth0");
return (pkt);
}
string callback_name("");
Pkt6Ptr callback_packet;
int
pkt6_receive_callout(CalloutHandle& callout_handle) {
printf("pkt6_receive_callout called!");
callback_name = string("pkt6_receive");
callout_handle.getArgument("pkt6", callback_packet);
return (0);
}
// Checks if callouts installed on pkt6_received are indeed called
// Note that the test name does not follow test naming convention,
// but the proper hook name is "pkt6_receive".
TEST_F(Dhcpv6SrvTest, Hook_pkt6_receive) {
// This calls Dhcpv6Srv::ctor, which registers hook names
NakedDhcpv6Srv srv(0);
// Let's pretend there will be 3 libraries
CalloutManager callout_mgr(3);
// Let's pretent we're the library 0
EXPECT_NO_THROW(callout_mgr.setLibraryIndex(0));
EXPECT_NO_THROW( callout_mgr.registerCallout("pkt6_receive", pkt6_receive_callout) );
// Let's create a REQUEST
Pkt6Ptr req = Pkt6Ptr(captureEmpty());
// Simulate that we have received that traffic
srv.fakeReceive(req);
// Server will now process to run its normal loop, but instead of calling
// IfaceMgr::receive6(), it will read all packets from the list set by
// fakeReceive()
// In particular, it should call registered pkt6_receive callback.
srv.run();
}
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test /// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
/// to call processX() methods. /// to call processX() methods.

View File

@@ -16,11 +16,15 @@
#include <dhcpsrv/dhcpsrv_log.h> #include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/lease_mgr_factory.h> #include <dhcpsrv/lease_mgr_factory.h>
#include <hooks/server_hooks.h>
#include <hooks/hooks_manager.h>
#include <cstring> #include <cstring>
#include <vector> #include <vector>
#include <string.h> #include <string.h>
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::hooks;
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
@@ -161,6 +165,9 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
default: default:
isc_throw(BadValue, "Invalid/unsupported allocation algorithm"); isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
} }
// Register hook points
hook_index_lease6_select_ = ServerHooks::getServerHooks().registerHook("lease6_select");
} }
Lease6Ptr Lease6Ptr
@@ -168,7 +175,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid, const DuidPtr& duid,
uint32_t iaid, uint32_t iaid,
const IOAddress& hint, const IOAddress& hint,
bool fake_allocation /* = false */ ) { bool fake_allocation,
const isc::hooks::CalloutHandlePtr& callout_handle) {
try { try {
// That check is not necessary. We create allocator in AllocEngine // That check is not necessary. We create allocator in AllocEngine
@@ -201,7 +209,8 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
/// implemented /// implemented
// the hint is valid and not currently used, let's create a lease for it // the hint is valid and not currently used, let's create a lease for it
Lease6Ptr lease = createLease6(subnet, duid, iaid, hint, fake_allocation); Lease6Ptr lease = createLease6(subnet, duid, iaid, hint, callout_handle,
fake_allocation);
// It can happen that the lease allocation failed (we could have lost // It can happen that the lease allocation failed (we could have lost
// the race condition. That means that the hint is lo longer usable and // the race condition. That means that the hint is lo longer usable and
@@ -212,7 +221,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
} else { } else {
if (existing->expired()) { if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid, return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation)); callout_handle, fake_allocation));
} }
} }
@@ -246,7 +255,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// there's no existing lease for selected candidate, so it is // there's no existing lease for selected candidate, so it is
// free. Let's allocate it. // free. Let's allocate it.
Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate, Lease6Ptr lease = createLease6(subnet, duid, iaid, candidate,
fake_allocation); callout_handle, fake_allocation);
if (lease) { if (lease) {
return (lease); return (lease);
} }
@@ -257,7 +266,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
} else { } else {
if (existing->expired()) { if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid, return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation)); callout_handle, fake_allocation));
} }
} }
@@ -438,6 +447,7 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
const Subnet6Ptr& subnet, const Subnet6Ptr& subnet,
const DuidPtr& duid, const DuidPtr& duid,
uint32_t iaid, uint32_t iaid,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation /*= false */ ) { bool fake_allocation /*= false */ ) {
if (!expired->expired()) { if (!expired->expired()) {
@@ -461,6 +471,42 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
/// @todo: log here that the lease was reused (there's ticket #2524 for /// @todo: log here that the lease was reused (there's ticket #2524 for
/// logging in libdhcpsrv) /// logging in libdhcpsrv)
// Let's execute all callouts registered for lease6_ia_added
if (callout_handle &&
HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
// Delete all previous arguments
callout_handle->deleteAllArguments();
// Clear skip flag if it was set in previous callouts
callout_handle->setSkip(false);
// Pass necessary arguments
// Subnet from which we do the allocation
callout_handle->setArgument("subnet6", subnet);
// Is this solicit (fake = true) or request (fake = false)
callout_handle->setArgument("fake_allocation", fake_allocation);
callout_handle->setArgument("lease6", expired);
// This is the first callout, so no need to clear any arguments
HooksManager::getHooksManager().callCallouts(hook_index_lease6_select_,
*callout_handle);
// Callouts decided to skip the action. This means that the lease is not
// assigned, so the client will get NoAddrAvail as a result. The lease
// won't be inserted into the
if (callout_handle->getSkip()) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_HOOKS, DHCPSRV_HOOK_LEASE6_IA_ADD_SKIP);
return (Lease6Ptr());
}
// Let's use whatever callout returned. Hopefully it is the same lease
// we handled to it.
callout_handle->getArgument("lease6", expired);
}
if (!fake_allocation) { if (!fake_allocation) {
// for REQUEST we do update the lease // for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease6(expired); LeaseMgrFactory::instance().updateLease6(expired);
@@ -517,12 +563,49 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
const DuidPtr& duid, const DuidPtr& duid,
uint32_t iaid, uint32_t iaid,
const IOAddress& addr, const IOAddress& addr,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation /*= false */ ) { bool fake_allocation /*= false */ ) {
Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, duid, iaid, Lease6Ptr lease(new Lease6(Lease6::LEASE_IA_NA, addr, duid, iaid,
subnet->getPreferred(), subnet->getValid(), subnet->getPreferred(), subnet->getValid(),
subnet->getT1(), subnet->getT2(), subnet->getID())); subnet->getT1(), subnet->getT2(), subnet->getID()));
// Let's execute all callouts registered for lease6_ia_added
if (callout_handle &&
HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
// Delete all previous arguments
callout_handle->deleteAllArguments();
// Clear skip flag if it was set in previous callouts
callout_handle->setSkip(false);
// Pass necessary arguments
// Subnet from which we do the allocation
callout_handle->setArgument("subnet6", subnet);
// Is this solicit (fake = true) or request (fake = false)
callout_handle->setArgument("fake_allocation", fake_allocation);
callout_handle->setArgument("lease6", lease);
// This is the first callout, so no need to clear any arguments
HooksManager::getHooksManager().callCallouts(hook_index_lease6_select_,
*callout_handle);
// Callouts decided to skip the action. This means that the lease is not
// assigned, so the client will get NoAddrAvail as a result. The lease
// won't be inserted into the
if (callout_handle->getSkip()) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_HOOKS, DHCPSRV_HOOK_LEASE6_IA_ADD_SKIP);
return (Lease6Ptr());
}
// Let's use whatever callout returned. Hopefully it is the same lease
// we handled to it.
callout_handle->getArgument("lease6", lease);
}
if (!fake_allocation) { if (!fake_allocation) {
// That is a real (REQUEST) allocation // That is a real (REQUEST) allocation
bool status = LeaseMgrFactory::instance().addLease(lease); bool status = LeaseMgrFactory::instance().addLease(lease);

View File

@@ -20,6 +20,7 @@
#include <dhcp/hwaddr.h> #include <dhcp/hwaddr.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/lease_mgr.h> #include <dhcpsrv/lease_mgr.h>
#include <hooks/callout_handle.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
@@ -235,13 +236,17 @@ protected:
/// @param hint a hint that the client provided /// @param hint a hint that the client provided
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking /// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true) /// an address for SOLICIT that is not really allocated (true)
/// @param callout_handle a callout handle (used in hooks). A lease callouts
/// will be executed if this parameter is passed.
///
/// @return Allocated IPv6 lease (or NULL if allocation failed) /// @return Allocated IPv6 lease (or NULL if allocation failed)
Lease6Ptr Lease6Ptr
allocateAddress6(const Subnet6Ptr& subnet, allocateAddress6(const Subnet6Ptr& subnet,
const DuidPtr& duid, const DuidPtr& duid,
uint32_t iaid, uint32_t iaid,
const isc::asiolink::IOAddress& hint, const isc::asiolink::IOAddress& hint,
bool fake_allocation); bool fake_allocation,
const isc::hooks::CalloutHandlePtr& callout_handle);
/// @brief Destructor. Used during DHCPv6 service shutdown. /// @brief Destructor. Used during DHCPv6 service shutdown.
virtual ~AllocEngine(); virtual ~AllocEngine();
@@ -276,12 +281,15 @@ private:
/// @param duid client's DUID /// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us /// @param iaid IAID from the IA_NA container the client sent to us
/// @param addr an address that was selected and is confirmed to be available /// @param addr an address that was selected and is confirmed to be available
/// @param callout_handle a callout handle (used in hooks). A lease callouts
/// will be executed if this parameter is passed.
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking /// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true) /// an address for SOLICIT that is not really allocated (true)
/// @return allocated lease (or NULL in the unlikely case of the lease just /// @return allocated lease (or NULL in the unlikely case of the lease just
/// becomed unavailable) /// becomed unavailable)
Lease6Ptr createLease6(const Subnet6Ptr& subnet, const DuidPtr& duid, Lease6Ptr createLease6(const Subnet6Ptr& subnet, const DuidPtr& duid,
uint32_t iaid, const isc::asiolink::IOAddress& addr, uint32_t iaid, const isc::asiolink::IOAddress& addr,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation = false); bool fake_allocation = false);
/// @brief Reuses expired IPv4 lease /// @brief Reuses expired IPv4 lease
@@ -313,12 +321,15 @@ private:
/// @param subnet subnet the lease is allocated from /// @param subnet subnet the lease is allocated from
/// @param duid client's DUID /// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us /// @param iaid IAID from the IA_NA container the client sent to us
/// @param callout_handle a callout handle (used in hooks). A lease callouts
/// will be executed if this parameter is passed.
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking /// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true) /// an address for SOLICIT that is not really allocated (true)
/// @return refreshed lease /// @return refreshed lease
/// @throw BadValue if trying to recycle lease that is still valid /// @throw BadValue if trying to recycle lease that is still valid
Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet, Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet,
const DuidPtr& duid, uint32_t iaid, const DuidPtr& duid, uint32_t iaid,
const isc::hooks::CalloutHandlePtr& callout_handle,
bool fake_allocation = false); bool fake_allocation = false);
/// @brief a pointer to currently used allocator /// @brief a pointer to currently used allocator
@@ -326,6 +337,9 @@ private:
/// @brief number of attempts before we give up lease allocation (0=unlimited) /// @brief number of attempts before we give up lease allocation (0=unlimited)
unsigned int attempts_; unsigned int attempts_;
/// @brief hook name index (used in hooks callouts)
int hook_index_lease6_select_;
}; };
}; // namespace isc::dhcp }; // namespace isc::dhcp

View File

@@ -262,6 +262,11 @@ void CfgMgr::deleteSubnets6() {
subnets6_.clear(); subnets6_.clear();
} }
const Subnet6Collection& CfgMgr::getSubnets6() {
return (subnets6_);
}
std::string CfgMgr::getDataDir() { std::string CfgMgr::getDataDir() {
return (datadir_); return (datadir_);
} }

View File

@@ -201,6 +201,15 @@ public:
/// completely new? /// completely new?
void deleteSubnets6(); void deleteSubnets6();
/// @brief returns const reference to all subnets6
///
/// This is used in a hook (subnet6_select), where the hook is able
/// to choose a different subnet. Server code has to offer a list
/// of possible choices (i.e. all subnets).
/// @return const reference to Subnet6 collection
const Subnet6Collection& getSubnets6();
/// @brief get IPv4 subnet by address /// @brief get IPv4 subnet by address
/// ///
/// Finds a matching subnet, based on an address. This can be used /// Finds a matching subnet, based on an address. This can be used

View File

@@ -50,6 +50,9 @@ const int DHCPSRV_DBG_TRACE_DETAIL = DBGLVL_TRACE_DETAIL;
/// Record detailed (and verbose) data on the server. /// Record detailed (and verbose) data on the server.
const int DHCPSRV_DBG_TRACE_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA; const int DHCPSRV_DBG_TRACE_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA;
// Trace hook related operations
const int DHCPSRV_HOOKS = DBGLVL_TRACE_BASIC;
///@} ///@}

View File

@@ -121,6 +121,12 @@ the database access parameters are changed: in the latter case, the
server closes the currently open database, and opens a database using server closes the currently open database, and opens a database using
the new parameters. the new parameters.
% DHCPSRV_HOOK_LEASE6_IA_ADD_SKIP Lease6 (non-temporary) creation was skipped, because of callout skip flag.
This debug message is printed when a callout installed on lease6_ia_assign
hook point sets a skip flag. It means that the server was told that no lease6
should be assigned. Server will not put that lease in its database and the client
will get a NoAddrsAvail for that IA_NA option.
% DHCPSRV_INVALID_ACCESS invalid database access string: %1 % DHCPSRV_INVALID_ACCESS invalid database access string: %1
This is logged when an attempt has been made to parse a database access string This is logged when an attempt has been made to parse a database access string
and the attempt ended in error. The access string in question - which and the attempt ended in error. The access string in question - which

View File

@@ -69,6 +69,7 @@ libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
libdhcpsrv_unittests_LDADD += $(top_builddir)/src/lib/hooks/libb10-hooks.la
libdhcpsrv_unittests_LDADD += $(GTEST_LDADD) libdhcpsrv_unittests_LDADD += $(GTEST_LDADD)
endif endif

View File

@@ -25,6 +25,8 @@
#include <dhcpsrv/tests/test_utils.h> #include <dhcpsrv/tests/test_utils.h>
#include <hooks/callout_handle.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@@ -37,6 +39,7 @@
using namespace std; using namespace std;
using namespace isc; using namespace isc;
using namespace isc::asiolink; using namespace isc::asiolink;
using namespace isc::hooks;
using namespace isc::dhcp; using namespace isc::dhcp;
using namespace isc::dhcp::test; using namespace isc::dhcp::test;
@@ -203,7 +206,7 @@ TEST_F(AllocEngine6Test, simpleAlloc6) {
ASSERT_TRUE(engine); ASSERT_TRUE(engine);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"), Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
false); false, CalloutHandlePtr());
// Check that we got a lease // Check that we got a lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -226,7 +229,7 @@ TEST_F(AllocEngine6Test, fakeAlloc6) {
ASSERT_TRUE(engine); ASSERT_TRUE(engine);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"), Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
true); true, CalloutHandlePtr());
// Check that we got a lease // Check that we got a lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -248,7 +251,7 @@ TEST_F(AllocEngine6Test, allocWithValidHint6) {
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("2001:db8:1::15"), IOAddress("2001:db8:1::15"),
false); false, CalloutHandlePtr());
// Check that we got a lease // Check that we got a lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -286,7 +289,7 @@ TEST_F(AllocEngine6Test, allocWithUsedHint6) {
// twice. // twice.
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("2001:db8:1::1f"), IOAddress("2001:db8:1::1f"),
false); false, CalloutHandlePtr());
// Check that we got a lease // Check that we got a lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -319,7 +322,7 @@ TEST_F(AllocEngine6Test, allocBogusHint6) {
// with the normal allocation // with the normal allocation
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("3000::abc"), IOAddress("3000::abc"),
false); false, CalloutHandlePtr());
// Check that we got a lease // Check that we got a lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -345,12 +348,12 @@ TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
// Allocations without subnet are not allowed // Allocations without subnet are not allowed
Lease6Ptr lease = engine->allocateAddress6(Subnet6Ptr(), duid_, iaid_, Lease6Ptr lease = engine->allocateAddress6(Subnet6Ptr(), duid_, iaid_,
IOAddress("::"), false); IOAddress("::"), false, CalloutHandlePtr());
ASSERT_FALSE(lease); ASSERT_FALSE(lease);
// Allocations without DUID are not allowed either // Allocations without DUID are not allowed either
lease = engine->allocateAddress6(subnet_, DuidPtr(), iaid_, lease = engine->allocateAddress6(subnet_, DuidPtr(), iaid_,
IOAddress("::"), false); IOAddress("::"), false, CalloutHandlePtr());
ASSERT_FALSE(lease); ASSERT_FALSE(lease);
} }
@@ -439,7 +442,7 @@ TEST_F(AllocEngine6Test, smallPool6) {
cfg_mgr.addSubnet6(subnet_); cfg_mgr.addSubnet6(subnet_);
Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"), Lease6Ptr lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
false); false, CalloutHandlePtr());
// Check that we got that single lease // Check that we got that single lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
@@ -485,7 +488,7 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
// There is just a single address in the pool and allocated it to someone // There is just a single address in the pool and allocated it to someone
// else, so the allocation should fail // else, so the allocation should fail
Lease6Ptr lease2 = engine->allocateAddress6(subnet_, duid_, iaid_, Lease6Ptr lease2 = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress("::"), false); IOAddress("::"), false, CalloutHandlePtr());
EXPECT_FALSE(lease2); EXPECT_FALSE(lease2);
} }
@@ -519,7 +522,7 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
// CASE 1: Asking for any address // CASE 1: Asking for any address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"), lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress("::"),
true); true, CalloutHandlePtr());
// Check that we got that single lease // Check that we got that single lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ(addr.toText(), lease->addr_.toText()); EXPECT_EQ(addr.toText(), lease->addr_.toText());
@@ -529,7 +532,7 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
// CASE 2: Asking specifically for this address // CASE 2: Asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress(addr.toText()), lease = engine->allocateAddress6(subnet_, duid_, iaid_, IOAddress(addr.toText()),
true); true, CalloutHandlePtr());
// Check that we got that single lease // Check that we got that single lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);
EXPECT_EQ(addr.toText(), lease->addr_.toText()); EXPECT_EQ(addr.toText(), lease->addr_.toText());
@@ -563,7 +566,8 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
// A client comes along, asking specifically for this address // A client comes along, asking specifically for this address
lease = engine->allocateAddress6(subnet_, duid_, iaid_, lease = engine->allocateAddress6(subnet_, duid_, iaid_,
IOAddress(addr.toText()), false); IOAddress(addr.toText()), false,
CalloutHandlePtr());
// Check that he got that single lease // Check that he got that single lease
ASSERT_TRUE(lease); ASSERT_TRUE(lease);

View File

@@ -34,6 +34,7 @@ libb10_hooks_la_SOURCES += hooks_log.cc hooks_log.h
libb10_hooks_la_SOURCES += library_handle.cc library_handle.h libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
libb10_hooks_la_SOURCES += library_manager.cc library_manager.h libb10_hooks_la_SOURCES += library_manager.cc library_manager.h
libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
libb10_hooks_la_SOURCES += hooks_manager.cc hooks_manager.h
nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h

View File

@@ -353,6 +353,9 @@ private:
bool skip_; bool skip_;
}; };
/// a shared pointer to CalloutHandle object
typedef boost::shared_ptr<CalloutHandle> CalloutHandlePtr;
} // namespace util } // namespace util
} // namespace isc } // namespace isc