From: Marcin Siodelski Date: Wed, 6 Jul 2016 10:28:49 +0000 (+0200) Subject: [4497] Enable copying retrieved options in callouts. X-Git-Tag: trac4551_base~23^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b2f0336a2c01a01fafd1b52c73b9e1985f6efa0;p=thirdparty%2Fkea.git [4497] Enable copying retrieved options in callouts. --- diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index 5eef7e0d56..3be5ec5f1c 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -467,6 +467,9 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& query) const { // We're reusing callout_handle from previous calls callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(query); + // Set new arguments callout_handle->setArgument("query4", query); callout_handle->setArgument("subnet4", subnet); @@ -735,6 +738,9 @@ Dhcpv4Srv::run_one() { // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy resp4_options_copy(rsp); + // Pass incoming packet as argument callout_handle->setArgument("response4", rsp); @@ -804,6 +810,9 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) { // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(query); + // Pass incoming packet as argument callout_handle->setArgument("query4", query); @@ -894,6 +903,9 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) { // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(query); + // Pass incoming packet as argument callout_handle->setArgument("query4", query); @@ -983,6 +995,10 @@ Dhcpv4Srv::processPacket(Pkt4Ptr& query, Pkt4Ptr& rsp) { // Clear skip flag if it was set in previous callouts callout_handle->setStatus(CalloutHandle::NEXT_STEP_CONTINUE); + // Enable copying options from the query and response packet within + // hook library. + ScopedEnableOptionsCopy query_resp_options_copy(query, rsp); + // Set our response callout_handle->setArgument("response4", rsp); @@ -2064,6 +2080,9 @@ Dhcpv4Srv::processRelease(Pkt4Ptr& release) { // Delete all previous arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(release); + // Pass the original packet callout_handle->setArgument("query4", release); @@ -2207,6 +2226,9 @@ Dhcpv4Srv::declineLease(const Lease4Ptr& lease, const Pkt4Ptr& decline) { // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(decline); + // Pass incoming Decline and the lease to be declined. callout_handle->setArgument("lease4", lease); callout_handle->setArgument("query4", decline); diff --git a/src/bin/dhcp4/tests/hooks_unittest.cc b/src/bin/dhcp4/tests/hooks_unittest.cc index 41cf65e54f..9970cbb1c0 100644 --- a/src/bin/dhcp4/tests/hooks_unittest.cc +++ b/src/bin/dhcp4/tests/hooks_unittest.cc @@ -200,6 +200,10 @@ public: callout_handle.getArgument("query4", callback_qry_pkt4_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } return (0); } @@ -245,6 +249,11 @@ public: callout_handle.getArgument("query4", callback_qry_pkt4_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -312,6 +321,15 @@ public: callout_handle.getArgument("query4", callback_qry_pkt4_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + + if (callback_resp_pkt4_) { + callback_resp_options_copy_ = callback_resp_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -375,6 +393,11 @@ public: callout_handle.getArgument("response4", callback_resp_pkt4_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_resp_pkt4_) { + callback_resp_options_copy_ = callback_resp_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -417,6 +440,11 @@ public: callout_handle.getArgument("subnet4collection", callback_subnet4collection_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -454,6 +482,11 @@ public: callout_handle.getArgument("lease4", callback_lease4_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -471,6 +504,11 @@ public: callout_handle.getArgument("clientid", callback_clientid_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -484,6 +522,10 @@ public: callout_handle.getArgument("query4", callback_qry_pkt4_); callout_handle.getArgument("lease4", callback_lease4_); + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -509,6 +551,8 @@ public: callback_subnet4_.reset(); callback_subnet4collection_ = NULL; callback_argument_names_.clear(); + callback_qry_options_copy_ = false; + callback_resp_options_copy_ = false; } /// pointer to Dhcpv4Srv that is used in tests @@ -542,6 +586,15 @@ public: /// A list of all received arguments static vector callback_argument_names_; + + /// Flag indicating if copying retrieved options was enabled for + /// a query during callout execution. + static bool callback_qry_options_copy_; + + /// Flag indicating if copying retrieved options was enabled for + /// a response during callout execution. + static bool callback_resp_options_copy_; + }; // The following fields are used in testing pkt4_receive_callout. @@ -555,6 +608,8 @@ ClientIdPtr HooksDhcpv4SrvTest::callback_clientid_; Lease4Ptr HooksDhcpv4SrvTest::callback_lease4_; const Subnet4Collection* HooksDhcpv4SrvTest::callback_subnet4collection_; vector HooksDhcpv4SrvTest::callback_argument_names_; +bool HooksDhcpv4SrvTest::callback_qry_options_copy_; +bool HooksDhcpv4SrvTest::callback_resp_options_copy_; /// @brief Fixture class used to do basic library load/unload tests class LoadUnloadDhcpv4SrvTest : public ::testing::Test { @@ -623,6 +678,9 @@ TEST_F(HooksDhcpv4SrvTest, Buffer4ReceiveSimple) { expected_argument_names.push_back(string("query4")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // Checks if callouts installed on buffer4_receive is able to change @@ -728,6 +786,9 @@ TEST_F(HooksDhcpv4SrvTest, pkt4ReceiveSimple) { expected_argument_names.push_back(string("query4")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // Checks if callouts installed on pkt4_received is able to change @@ -865,6 +926,10 @@ TEST_F(HooksDhcpv4SrvTest, pkt4SendSimple) { sort(callback_argument_names_.begin(), callback_argument_names_.end()); sort(expected_argument_names.begin(), expected_argument_names.end()); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); + EXPECT_TRUE(callback_resp_options_copy_); } // Checks if callouts installed on pkt4_send is able to change @@ -1006,6 +1071,9 @@ TEST_F(HooksDhcpv4SrvTest, buffer4SendSimple) { vector expected_argument_names; expected_argument_names.push_back(string("response4")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_resp_options_copy_); } // Checks if callouts installed on buffer4_send are indeed called and that @@ -1139,6 +1207,9 @@ TEST_F(HooksDhcpv4SrvTest, subnet4SelectSimple) { // Compare that the available subnets are reported as expected EXPECT_TRUE((*exp_subnets)[0].get() == (*callback_subnet4collection_)[0].get()); EXPECT_TRUE((*exp_subnets)[1].get() == (*callback_subnet4collection_)[1].get()); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // This test checks if callout installed on subnet4_select hook point can pick @@ -1300,6 +1371,9 @@ TEST_F(HooksDhcpv4SrvTest, lease4RenewSimple) { EXPECT_TRUE(callback_argument_names_ == expected_argument_names); EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // This test verifies that a callout installed on lease4_renew can trigger @@ -1456,6 +1530,9 @@ TEST_F(HooksDhcpv4SrvTest, lease4ReleaseSimple) { sort(callback_argument_names_.begin(), callback_argument_names_.end()); sort(expected_argument_names.begin(), expected_argument_names.end()); EXPECT_TRUE(callback_argument_names_ == expected_argument_names); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // This test verifies that skip flag returned by a callout installed on the @@ -1564,6 +1641,9 @@ TEST_F(HooksDhcpv4SrvTest, HooksDecline) { // the lease manager) all match. EXPECT_EQ(addr, from_mgr->addr_); EXPECT_EQ(addr, callback_lease4_->addr_); + + // Pkt passed to a callout must be configured to copy retrieved options. + EXPECT_TRUE(callback_qry_options_copy_); } // Checks that decline4 hook is able to drop the packet. diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 78117d74ff..8d522575dc 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -480,6 +480,9 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { if (HooksManager::calloutsPresent(Hooks.hook_index_buffer6_receive_)) { CalloutHandlePtr callout_handle = getCalloutHandle(query); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(query); + // Delete previously set arguments callout_handle->deleteAllArguments(); @@ -575,6 +578,9 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(query); + // Pass incoming packet as argument callout_handle->setArgument("query6", query); @@ -717,6 +723,9 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) { if (HooksManager::calloutsPresent(Hooks.hook_index_pkt6_send_)) { CalloutHandlePtr callout_handle = getCalloutHandle(query); + // Enable copying options from the packets within hook library. + ScopedEnableOptionsCopy query_resp_options_copy(query, rsp); + // Delete all previous arguments callout_handle->deleteAllArguments(); @@ -1014,6 +1023,9 @@ Dhcpv6Srv::selectSubnet(const Pkt6Ptr& question) { // We're reusing callout_handle from previous calls callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(question); + // Set new arguments callout_handle->setArgument("query6", question); callout_handle->setArgument("subnet6", subnet); @@ -2023,6 +2035,9 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query, if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_release_)) { CalloutHandlePtr callout_handle = getCalloutHandle(query); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(query); + // Delete all previous arguments callout_handle->deleteAllArguments(); @@ -2706,6 +2721,9 @@ Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease, // Delete previously set arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(decline); + // Pass incoming packet as argument callout_handle->setArgument("query6", decline); callout_handle->setArgument("lease6", lease); diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc index dc2a9969c7..9576bb9cc6 100644 --- a/src/bin/dhcp6/tests/hooks_unittest.cc +++ b/src/bin/dhcp6/tests/hooks_unittest.cc @@ -147,6 +147,11 @@ public: callout_handle.getArgument("query6", callback_qry_pkt6_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -210,6 +215,11 @@ public: callout_handle.getArgument("query6", callback_qry_pkt6_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -284,6 +294,15 @@ public: callout_handle.getArgument("query6", callback_qry_pkt6_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + + if (callback_resp_pkt6_) { + callback_resp_options_copy_ = callback_resp_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -349,6 +368,11 @@ public: callout_handle.getArgument("subnet6collection", callback_subnet6collection_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -387,6 +411,11 @@ public: callout_handle.getArgument("ia_na", callback_ia_na_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -454,6 +483,11 @@ public: callout_handle.getArgument("ia_na", callback_ia_na_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -523,6 +557,11 @@ public: callout_handle.getArgument("lease6", callback_lease6_); callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -550,6 +589,10 @@ public: callout_handle.getArgument("query6", callback_qry_pkt6_); callout_handle.getArgument("lease6", callback_lease6_); + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -585,6 +628,8 @@ public: callback_ia_na_.reset(); callback_subnet6collection_ = NULL; callback_argument_names_.clear(); + callback_qry_options_copy_ = false; + callback_resp_options_copy_ = false; } /// Pointer to Dhcpv6Srv that is used in tests @@ -615,6 +660,14 @@ public: /// A list of all received arguments static vector callback_argument_names_; + + /// Flag indicating if copying retrieved options was enabled for + /// a query during callout execution. + static bool callback_qry_options_copy_; + + /// Flag indicating if copying retrieved options was enabled for + /// a response during callout execution. + static bool callback_resp_options_copy_; }; // The following parameters are used by callouts to override @@ -635,6 +688,8 @@ const Subnet6Collection* HooksDhcpv6SrvTest::callback_subnet6collection_; vector HooksDhcpv6SrvTest::callback_argument_names_; Lease6Ptr HooksDhcpv6SrvTest::callback_lease6_; boost::shared_ptr HooksDhcpv6SrvTest::callback_ia_na_; +bool HooksDhcpv6SrvTest::callback_qry_options_copy_; +bool HooksDhcpv6SrvTest::callback_resp_options_copy_; /// @brief Fixture class used to do basic library load/unload tests class LoadUnloadDhcpv6SrvTest : public ::testing::Test { @@ -702,6 +757,8 @@ TEST_F(HooksDhcpv6SrvTest, simpleBuffer6Receive) { expected_argument_names.push_back(string("query6")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + EXPECT_TRUE(callback_qry_options_copy_); } // Checks if callouts installed on buffer6_receive is able to change @@ -823,6 +880,8 @@ TEST_F(HooksDhcpv6SrvTest, simplePkt6Receive) { expected_argument_names.push_back(string("query6")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + EXPECT_TRUE(callback_qry_options_copy_); } // Checks if callouts installed on pkt6_received is able to change @@ -947,6 +1006,9 @@ TEST_F(HooksDhcpv6SrvTest, simplePkt6Send) { expected_argument_names.push_back(string("query6")); expected_argument_names.push_back(string("response6")); EXPECT_TRUE(expected_argument_names == callback_argument_names_); + + EXPECT_TRUE(callback_qry_options_copy_); + EXPECT_TRUE(callback_resp_options_copy_); } // Checks if callouts installed on pkt6_send is able to change @@ -1192,6 +1254,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SselectChange) { // in dynamic pool) EXPECT_TRUE((*subnets)[1]->inRange(addr_opt->getAddress())); EXPECT_TRUE((*subnets)[1]->inPool(Lease::TYPE_NA, addr_opt->getAddress())); + + EXPECT_TRUE(callback_qry_options_copy_); } // This test verifies that incoming (positive) RENEW can be handled properly, @@ -1291,6 +1355,8 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Renew) { // Check that the returned lease6 in callout is the same as the one in the // database EXPECT_TRUE(*callback_lease6_ == *l); + + EXPECT_TRUE(callback_qry_options_copy_); } // This test verifies that incoming (positive) RENEW can be handled properly, @@ -1537,6 +1603,8 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Release) { l = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA, *duid_, iaid, subnet_->getID()); ASSERT_FALSE(l); + + EXPECT_TRUE(callback_qry_options_copy_); } // This test verifies that incoming (positive) RELEASE can be handled properly, @@ -1907,6 +1975,8 @@ TEST_F(HooksDhcpv6SrvTest, basicLease6Decline) { // And that the parameters passed to callout are consistent with the database EXPECT_EQ(addr, from_mgr->addr_); EXPECT_EQ(addr, callback_lease6_->addr_); + + EXPECT_TRUE(callback_qry_options_copy_); } // Test that the lease6_decline hook point can handle SKIP status. diff --git a/src/lib/dhcp/pkt.h b/src/lib/dhcp/pkt.h index 21632cc45d..5c836d95ac 100644 --- a/src/lib/dhcp/pkt.h +++ b/src/lib/dhcp/pkt.h @@ -14,11 +14,67 @@ #include #include +#include + +#include namespace isc { namespace dhcp { +/// @brief RAII object enabling copying options retrieved from the +/// packet. +/// +/// This object enables copying retrieved options from a packet within +/// a scope in which this object exists. When the object goes out of scope +/// copying options is disabled. This is applicable in cases when the +/// server is going to invoke a callout (hook library) where copying options +/// must be enabled by default. When the callouts return copying options +/// should be disabled. The use of RAII object eliminates the need for +/// explicitly re-renabling options copying and is safer in case of +/// exceptions thrown by callouts and a presence of multiple exit points. +template +class ScopedEnableOptionsCopy { +public: + + /// @brief Pointer to an encapsulated packet. + typedef boost::shared_ptr PktTypePtr; + + /// @brief Constructor. + /// + /// Enables options copying on a packet(s). + /// + /// @param pkt1 Pointer to first packet. + /// @param pkt2 Optional pointer to the second packet. + ScopedEnableOptionsCopy(const PktTypePtr& pkt1, + const PktTypePtr& pkt2 = PktTypePtr()) + : pkts_(pkt1, pkt2) { + if (pkt1) { + pkt1->setCopyRetrievedOptions(true); + } + if (pkt2) { + pkt2->setCopyRetrievedOptions(true); + } + } + + /// @brief Destructor. + /// + /// Disables options copying on a packets. + ~ScopedEnableOptionsCopy() { + if (pkts_.first) { + pkts_.first->setCopyRetrievedOptions(false); + } + if (pkts_.second) { + pkts_.second->setCopyRetrievedOptions(false); + } + } + +private: + + /// @brief Holds a pointers to the packets. + std::pair pkts_; +}; + /// @brief Base class for classes representing DHCP messages. /// /// This is a base class that holds common information (e.g. source diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 596d81df5a..1f8d9d4e3d 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -1050,6 +1050,9 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx, // Delete all previous arguments ctx.callout_handle_->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(ctx.query_); + // Pass necessary arguments // Pass the original packet @@ -1120,6 +1123,9 @@ Lease6Ptr AllocEngine::createLease6(ClientContext6& ctx, // Delete all previous arguments ctx.callout_handle_->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(ctx.query_); + // Pass necessary arguments // Pass the original packet @@ -1338,6 +1344,9 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) { // Delete all previous arguments callout_handle->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query6_options_copy(ctx.query_); + // Pass the original packet callout_handle->setArgument("query6", ctx.query_); @@ -2524,6 +2533,9 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr) { // Delete all previous arguments ctx.callout_handle_->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(ctx.query_); + // Pass necessary arguments // Pass the original client query ctx.callout_handle_->setArgument("query4", ctx.query_); @@ -2629,6 +2641,9 @@ AllocEngine::renewLease4(const Lease4Ptr& lease, // Delete all previous arguments ctx.callout_handle_->deleteAllArguments(); + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(ctx.query_); + // Subnet from which we do the allocation. Convert the general subnet // pointer to a pointer to a Subnet4. Note that because we are using // boost smart pointers here, we need to do the cast using the boost @@ -2703,6 +2718,9 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired, if (ctx.callout_handle_ && HooksManager::getHooksManager() .calloutsPresent(hook_index_lease4_select_)) { + // Enable copying options from the packet within hook library. + ScopedEnableOptionsCopy query4_options_copy(ctx.query_); + // Delete all previous arguments ctx.callout_handle_->deleteAllArguments(); diff --git a/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc index ba7c7e665d..ae02064506 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc @@ -45,6 +45,7 @@ public: callback_addr_original_ = IOAddress("::"); callback_addr_updated_ = IOAddress("::"); callback_qry_pkt6_.reset(); + callback_qry_options_copy_ = false; } /// callback that stores received callout name and received values @@ -61,6 +62,12 @@ public: callback_addr_original_ = callback_lease6_->addr_; callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt6_) { + callback_qry_options_copy_ = + callback_qry_pkt6_->isCopyRetrievedOptions(); + } + return (0); } @@ -102,6 +109,7 @@ public: static bool callback_fake_allocation_; static vector callback_argument_names_; static Pkt6Ptr callback_qry_pkt6_; + static bool callback_qry_options_copy_; }; // For some reason intialization within a class makes the linker confused. @@ -122,6 +130,7 @@ Lease6Ptr HookAllocEngine6Test::callback_lease6_; bool HookAllocEngine6Test::callback_fake_allocation_; vector HookAllocEngine6Test::callback_argument_names_; Pkt6Ptr HookAllocEngine6Test::callback_qry_pkt6_; +bool HookAllocEngine6Test::callback_qry_options_copy_; // This test checks if the lease6_select callout is executed and expected // parameters as passed. @@ -195,6 +204,8 @@ TEST_F(HookAllocEngine6Test, lease6_select) { sort(expected_argument_names.begin(), expected_argument_names.end()); EXPECT_TRUE(callback_argument_names_ == expected_argument_names); + + EXPECT_TRUE(callback_qry_options_copy_); } // This test checks if lease6_select callout is able to override the values @@ -282,6 +293,7 @@ public: callback_addr_original_ = IOAddress("::"); callback_addr_updated_ = IOAddress("::"); callback_qry_pkt4_.reset(); + callback_qry_options_copy_ = false; } /// callback that stores received callout name and received values @@ -298,6 +310,12 @@ public: callback_addr_original_ = callback_lease4_->addr_; callback_argument_names_ = callout_handle.getArgumentNames(); + + if (callback_qry_pkt4_) { + callback_qry_options_copy_ = + callback_qry_pkt4_->isCopyRetrievedOptions(); + } + return (0); } @@ -337,6 +355,7 @@ public: static bool callback_fake_allocation_; static vector callback_argument_names_; static Pkt4Ptr callback_qry_pkt4_; + static bool callback_qry_options_copy_; }; // For some reason intialization within a class makes the linker confused. @@ -356,6 +375,7 @@ Lease4Ptr HookAllocEngine4Test::callback_lease4_; bool HookAllocEngine4Test::callback_fake_allocation_; vector HookAllocEngine4Test::callback_argument_names_; Pkt4Ptr HookAllocEngine4Test::callback_qry_pkt4_; +bool HookAllocEngine4Test::callback_qry_options_copy_; // This test checks if the lease4_select callout is executed and expected // parameters as passed. @@ -428,6 +448,8 @@ TEST_F(HookAllocEngine4Test, lease4_select) { expected_argument_names.push_back("query4"); expected_argument_names.push_back("subnet4"); EXPECT_TRUE(callback_argument_names_ == expected_argument_names); + + EXPECT_TRUE(callback_qry_options_copy_); } // This test checks if lease4_select callout is able to override the values