Browse Source

[2994] lease4_select hook implemented.

Tomek Mrugalski 11 years ago
parent
commit
5b10e071de

+ 88 - 11
src/lib/dhcpsrv/alloc_engine.cc

@@ -29,11 +29,13 @@ using namespace isc::hooks;
 namespace {
 namespace {
 
 
 /// Structure that holds registered hook indexes
 /// Structure that holds registered hook indexes
-struct Dhcp6Hooks {
+struct AllocEngineHooks {
+    int hook_index_lease4_select_; ///< index for "lease4_receive" hook point
     int hook_index_lease6_select_; ///< index for "lease6_receive" hook point
     int hook_index_lease6_select_; ///< index for "lease6_receive" hook point
 
 
     /// Constructor that registers hook points for AllocationEngine
     /// Constructor that registers hook points for AllocationEngine
-    Dhcp6Hooks() {
+    AllocEngineHooks() {
+        hook_index_lease6_select_ = HooksManager::registerHook("lease4_select");
         hook_index_lease6_select_ = HooksManager::registerHook("lease6_select");
         hook_index_lease6_select_ = HooksManager::registerHook("lease6_select");
     }
     }
 };
 };
@@ -42,7 +44,7 @@ struct Dhcp6Hooks {
 // will be instantiated (and the constructor run) when the module is loaded.
 // will be instantiated (and the constructor run) when the module is loaded.
 // As a result, the hook indexes will be defined before any method in this
 // As a result, the hook indexes will be defined before any method in this
 // module is called.
 // module is called.
-Dhcp6Hooks Hooks;
+AllocEngineHooks Hooks;
 
 
 }; // anonymous namespace
 }; // anonymous namespace
 
 
@@ -187,6 +189,7 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
     }
     }
 
 
     // Register hook points
     // Register hook points
+    hook_index_lease4_select_ = Hooks.hook_index_lease4_select_;
     hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
     hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
 }
 }
 
 
@@ -312,7 +315,8 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
                               const ClientIdPtr& clientid,
                               const ClientIdPtr& clientid,
                               const HWAddrPtr& hwaddr,
                               const HWAddrPtr& hwaddr,
                               const IOAddress& hint,
                               const IOAddress& hint,
-                              bool fake_allocation /* = false */ ) {
+                              bool fake_allocation,
+                              const isc::hooks::CalloutHandlePtr& callout_handle) {
 
 
     try {
     try {
         // Allocator is always created in AllocEngine constructor and there is
         // Allocator is always created in AllocEngine constructor and there is
@@ -365,7 +369,8 @@ AllocEngine::allocateAddress4(const SubnetPtr& 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
-                Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, hint, fake_allocation);
+                Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, 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
@@ -376,7 +381,7 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
             } else {
             } else {
                 if (existing->expired()) {
                 if (existing->expired()) {
                     return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
                     return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
-                                              fake_allocation));
+                                              callout_handle, fake_allocation));
                 }
                 }
 
 
             }
             }
@@ -410,7 +415,7 @@ AllocEngine::allocateAddress4(const SubnetPtr& 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.
                 Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, candidate,
                 Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, candidate,
-                                              fake_allocation);
+                                               callout_handle, fake_allocation);
                 if (lease) {
                 if (lease) {
                     return (lease);
                     return (lease);
                 }
                 }
@@ -421,7 +426,7 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
             } else {
             } else {
                 if (existing->expired()) {
                 if (existing->expired()) {
                     return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
                     return (reuseExpiredLease(existing, subnet, clientid, hwaddr,
-                                              fake_allocation));
+                                              callout_handle, fake_allocation));
                 }
                 }
             }
             }
 
 
@@ -515,7 +520,7 @@ Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
         // assigned, so the client will get NoAddrAvail as a result. The lease
         // assigned, so the client will get NoAddrAvail as a result. The lease
         // won't be inserted into the
         // won't be inserted into the
         if (callout_handle->getSkip()) {
         if (callout_handle->getSkip()) {
-            LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_IA_ADD_SKIP);
+            LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_SELECT_SKIP);
             return (Lease6Ptr());
             return (Lease6Ptr());
         }
         }
 
 
@@ -541,6 +546,7 @@ Lease4Ptr AllocEngine::reuseExpiredLease(Lease4Ptr& expired,
                                          const SubnetPtr& subnet,
                                          const SubnetPtr& subnet,
                                          const ClientIdPtr& clientid,
                                          const ClientIdPtr& clientid,
                                          const HWAddrPtr& hwaddr,
                                          const HWAddrPtr& hwaddr,
+                                         const isc::hooks::CalloutHandlePtr& callout_handle,
                                          bool fake_allocation /*= false */ ) {
                                          bool fake_allocation /*= false */ ) {
 
 
     if (!expired->expired()) {
     if (!expired->expired()) {
@@ -563,6 +569,39 @@ Lease4Ptr AllocEngine::reuseExpiredLease(Lease4Ptr& 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 lease4_select
+    if (callout_handle &&
+        HooksManager::getHooksManager().calloutsPresent(hook_index_lease4_select_)) {
+
+        // Delete all previous arguments
+        callout_handle->deleteAllArguments();
+
+        // Pass necessary arguments
+        // Subnet from which we do the allocation
+        callout_handle->setArgument("subnet4", subnet);
+
+        // Is this solicit (fake = true) or request (fake = false)
+        callout_handle->setArgument("fake_allocation", fake_allocation);
+
+        // The lease that will be assigned to a client
+        callout_handle->setArgument("lease4", expired);
+
+        // Call the callouts
+        HooksManager::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_DBG_HOOKS, DHCPSRV_HOOK_LEASE4_SELECT_SKIP);
+            return (Lease4Ptr());
+        }
+
+        // Let's use whatever callout returned. Hopefully it is the same lease
+        // we handled to it.
+        callout_handle->getArgument("lease4", expired);
+    }
+
     if (!fake_allocation) {
     if (!fake_allocation) {
         // for REQUEST we do update the lease
         // for REQUEST we do update the lease
         LeaseMgrFactory::instance().updateLease4(expired);
         LeaseMgrFactory::instance().updateLease4(expired);
@@ -587,7 +626,7 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
                                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
+    // Let's execute all callouts registered for lease6_select
     if (callout_handle &&
     if (callout_handle &&
         HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
         HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
 
 
@@ -613,7 +652,7 @@ Lease6Ptr AllocEngine::createLease6(const Subnet6Ptr& subnet,
         // assigned, so the client will get NoAddrAvail as a result. The lease
         // assigned, so the client will get NoAddrAvail as a result. The lease
         // won't be inserted into the
         // won't be inserted into the
         if (callout_handle->getSkip()) {
         if (callout_handle->getSkip()) {
-            LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_IA_ADD_SKIP);
+            LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_HOOKS, DHCPSRV_HOOK_LEASE6_SELECT_SKIP);
             return (Lease6Ptr());
             return (Lease6Ptr());
         }
         }
 
 
@@ -654,6 +693,7 @@ Lease4Ptr AllocEngine::createLease4(const SubnetPtr& subnet,
                                     const DuidPtr& clientid,
                                     const DuidPtr& clientid,
                                     const HWAddrPtr& hwaddr,
                                     const HWAddrPtr& hwaddr,
                                     const IOAddress& addr,
                                     const IOAddress& addr,
+                                    const isc::hooks::CalloutHandlePtr& callout_handle,
                                     bool fake_allocation /*= false */ ) {
                                     bool fake_allocation /*= false */ ) {
     if (!hwaddr) {
     if (!hwaddr) {
         isc_throw(BadValue, "Can't create a lease with NULL HW address");
         isc_throw(BadValue, "Can't create a lease with NULL HW address");
@@ -671,6 +711,43 @@ Lease4Ptr AllocEngine::createLease4(const SubnetPtr& subnet,
                                subnet->getT1(), subnet->getT2(), now,
                                subnet->getT1(), subnet->getT2(), now,
                                subnet->getID()));
                                subnet->getID()));
 
 
+    // Let's execute all callouts registered for lease4_select
+    if (callout_handle &&
+        HooksManager::getHooksManager().calloutsPresent(hook_index_lease4_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("subnet4", subnet);
+
+        // Is this solicit (fake = true) or request (fake = false)
+        callout_handle->setArgument("fake_allocation", fake_allocation);
+        callout_handle->setArgument("lease4", lease);
+
+        // This is the first callout, so no need to clear any arguments
+        HooksManager::callCallouts(hook_index_lease4_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_DBG_HOOKS, DHCPSRV_HOOK_LEASE4_SELECT_SKIP);
+            return (Lease4Ptr());
+        }
+
+        // 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);

+ 13 - 3
src/lib/dhcpsrv/alloc_engine.h

@@ -194,13 +194,16 @@ 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 DISCOVER that is not really allocated (true)
     ///        an address for DISCOVER 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 IPv4 lease (or NULL if allocation failed)
     /// @return Allocated IPv4 lease (or NULL if allocation failed)
     Lease4Ptr
     Lease4Ptr
     allocateAddress4(const SubnetPtr& subnet,
     allocateAddress4(const SubnetPtr& subnet,
                      const ClientIdPtr& clientid,
                      const ClientIdPtr& clientid,
                      const HWAddrPtr& hwaddr,
                      const HWAddrPtr& hwaddr,
                      const isc::asiolink::IOAddress& hint,
                      const isc::asiolink::IOAddress& hint,
-                     bool fake_allocation);
+                     bool fake_allocation,
+                     const isc::hooks::CalloutHandlePtr& callout_handle);
 
 
     /// @brief Renews a IPv4 lease
     /// @brief Renews a IPv4 lease
     ///
     ///
@@ -262,6 +265,8 @@ private:
     /// @param clientid client identifier
     /// @param clientid client identifier
     /// @param hwaddr client's hardware address
     /// @param hwaddr client's hardware address
     /// @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 DISCOVER that is not really allocated (true)
     ///        an address for DISCOVER 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
@@ -269,6 +274,7 @@ private:
     Lease4Ptr createLease4(const SubnetPtr& subnet, const DuidPtr& clientid,
     Lease4Ptr createLease4(const SubnetPtr& subnet, const DuidPtr& clientid,
                            const HWAddrPtr& hwaddr,
                            const HWAddrPtr& hwaddr,
                            const isc::asiolink::IOAddress& addr,
                            const isc::asiolink::IOAddress& addr,
+                           const isc::hooks::CalloutHandlePtr& callout_handle,
                            bool fake_allocation = false);
                            bool fake_allocation = false);
 
 
     /// @brief creates a lease and inserts it in LeaseMgr if necessary
     /// @brief creates a lease and inserts it in LeaseMgr if necessary
@@ -302,6 +308,8 @@ private:
     /// @param subnet subnet the lease is allocated from
     /// @param subnet subnet the lease is allocated from
     /// @param clientid client identifier
     /// @param clientid client identifier
     /// @param hwaddr client's hardware address
     /// @param hwaddr client's hardware address
+    /// @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 DISCOVER that is not really allocated (true)
     ///        an address for DISCOVER that is not really allocated (true)
     /// @return refreshed lease
     /// @return refreshed lease
@@ -309,6 +317,7 @@ private:
     Lease4Ptr reuseExpiredLease(Lease4Ptr& expired, const SubnetPtr& subnet,
     Lease4Ptr reuseExpiredLease(Lease4Ptr& expired, const SubnetPtr& subnet,
                                 const ClientIdPtr& clientid,
                                 const ClientIdPtr& clientid,
                                 const HWAddrPtr& hwaddr,
                                 const HWAddrPtr& hwaddr,
+                                const isc::hooks::CalloutHandlePtr& callout_handle,
                                 bool fake_allocation = false);
                                 bool fake_allocation = false);
 
 
     /// @brief Reuses expired IPv6 lease
     /// @brief Reuses expired IPv6 lease
@@ -338,8 +347,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_;
+    // hook name indexes (used in hooks callouts)
+    int hook_index_lease4_select_; ///< index for lease4_select hook
+    int hook_index_lease6_select_; ///< index for lease6_select hook
 };
 };
 
 
 }; // namespace isc::dhcp
 }; // namespace isc::dhcp

+ 8 - 2
src/lib/dhcpsrv/dhcpsrv_messages.mes

@@ -121,8 +121,14 @@ 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_assign
+% DHCPSRV_HOOK_LEASE4_SELECT_SKIP Lease4 creation was skipped, because of callout skip flag.
+This debug message is printed when a callout installed on lease4_select
+hook point sets a skip flag. It means that the server was told that no lease4
+should be assigned. The server will not put that lease in its database and the client
+will get a NAK packet.
+
+% DHCPSRV_HOOK_LEASE6_SELECT_SKIP Lease6 (non-temporary) creation was skipped, because of callout skip flag.
+This debug message is printed when a callout installed on lease6_select
 hook point sets a skip flag. It means that the server was told that no lease6
 hook point sets a skip flag. It means that the server was told that no lease6
 should be assigned. The server will not put that lease in its database and the client
 should be assigned. The server will not put that lease in its database and the client
 will get a NoAddrsAvail for that IA_NA option.
 will get a NoAddrsAvail for that IA_NA option.

+ 18 - 13
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc

@@ -592,7 +592,8 @@ TEST_F(AllocEngine4Test, simpleAlloc4) {
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
-                                               IOAddress("0.0.0.0"), false);
+                                               IOAddress("0.0.0.0"), false,
+                                               CalloutHandlePtr());
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -615,7 +616,8 @@ TEST_F(AllocEngine4Test, fakeAlloc4) {
     ASSERT_TRUE(engine);
     ASSERT_TRUE(engine);
 
 
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
-                                               IOAddress("0.0.0.0"), true);
+                                               IOAddress("0.0.0.0"), true,
+                                               CalloutHandlePtr());
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -638,7 +640,7 @@ TEST_F(AllocEngine4Test, allocWithValidHint4) {
 
 
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
                                                IOAddress("192.0.2.105"),
                                                IOAddress("192.0.2.105"),
-                                               false);
+                                               false, CalloutHandlePtr());
 
 
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -678,7 +680,7 @@ TEST_F(AllocEngine4Test, allocWithUsedHint4) {
     // twice.
     // twice.
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
                                                IOAddress("192.0.2.106"),
                                                IOAddress("192.0.2.106"),
-                                               false);
+                                               false, CalloutHandlePtr());
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -712,7 +714,7 @@ TEST_F(AllocEngine4Test, allocBogusHint4) {
     // with the normal allocation
     // with the normal allocation
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
                                                IOAddress("10.1.1.1"),
                                                IOAddress("10.1.1.1"),
-                                               false);
+                                               false, CalloutHandlePtr());
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -739,18 +741,19 @@ TEST_F(AllocEngine4Test, allocateAddress4Nulls) {
 
 
     // Allocations without subnet are not allowed
     // Allocations without subnet are not allowed
     Lease4Ptr lease = engine->allocateAddress4(SubnetPtr(), clientid_, hwaddr_,
     Lease4Ptr lease = engine->allocateAddress4(SubnetPtr(), clientid_, hwaddr_,
-                                               IOAddress("0.0.0.0"), false);
+                                               IOAddress("0.0.0.0"), false,
+                                               CalloutHandlePtr());
     EXPECT_FALSE(lease);
     EXPECT_FALSE(lease);
 
 
     // Allocations without HW address are not allowed
     // Allocations without HW address are not allowed
     lease = engine->allocateAddress4(subnet_, clientid_, HWAddrPtr(),
     lease = engine->allocateAddress4(subnet_, clientid_, HWAddrPtr(),
-                                     IOAddress("0.0.0.0"), false);
+                                     IOAddress("0.0.0.0"), false, CalloutHandlePtr());
     EXPECT_FALSE(lease);
     EXPECT_FALSE(lease);
 
 
     // Allocations without client-id are allowed
     // Allocations without client-id are allowed
     clientid_ = ClientIdPtr();
     clientid_ = ClientIdPtr();
     lease = engine->allocateAddress4(subnet_, ClientIdPtr(), hwaddr_,
     lease = engine->allocateAddress4(subnet_, ClientIdPtr(), hwaddr_,
-                                     IOAddress("0.0.0.0"), false);
+                                     IOAddress("0.0.0.0"), false, CalloutHandlePtr());
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
 
 
@@ -854,7 +857,7 @@ TEST_F(AllocEngine4Test, smallPool4) {
     cfg_mgr.addSubnet4(subnet_);
     cfg_mgr.addSubnet4(subnet_);
 
 
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
     Lease4Ptr lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                               false);
+                                               false, CalloutHandlePtr());
 
 
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -902,7 +905,8 @@ TEST_F(AllocEngine4Test, outOfAddresses4) {
     // else, so the allocation should fail
     // else, so the allocation should fail
 
 
     Lease4Ptr lease2 = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     Lease4Ptr lease2 = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
-                                                IOAddress("0.0.0.0"), false);
+                                                IOAddress("0.0.0.0"), false,
+                                                CalloutHandlePtr());
     EXPECT_FALSE(lease2);
     EXPECT_FALSE(lease2);
 }
 }
 
 
@@ -935,7 +939,7 @@ TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
 
 
     // CASE 1: Asking for any address
     // CASE 1: Asking for any address
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                     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());
@@ -945,7 +949,7 @@ TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
 
 
     // CASE 2: Asking specifically for this address
     // CASE 2: Asking specifically for this address
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, IOAddress(addr.toText()),
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_, 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());
@@ -972,7 +976,8 @@ TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
 
 
     // A client comes along, asking specifically for this address
     // A client comes along, asking specifically for this address
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
     lease = engine->allocateAddress4(subnet_, clientid_, hwaddr_,
-                                     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);