using namespace isc::hooks;
using namespace isc::config;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
configure(config);
// Let's just use one of the actual captured packets that we have.
- Pkt4Ptr pkt = isc::test::PktCaptures::captureRelayedDiscover();
+ Pkt4Ptr pkt = PktCaptures::captureRelayedDiscover();
// We just need to tweak it a it, to pretend that it's type is as desired.
// Note that when receiving a packet, its on-wire form is stored in data_
this fact; otherwise the client will think the lease was renewed and continue
to operate under this assumption.
+@subsection dhcpv6HooksLease6Decline lease6_decline
+
+ - @b Arguments:
+ - name: @b query6, type: isc::dhcp::PktPtr, direction: <b>in</b>
+ - name: @b lease6, type: isc::dhcp::Lease6Ptr, direction: <b>in/out</b>
+
+ - @b Description: This callout is executed when the server engine is
+ about to decline an existing lease. The client's request is provided as
+ the "query6" argument and the existing lease with the appropriate fields
+ already modified is given in the "lease6" argument. The lease contains
+ the lease before it is being declined.
+
+ - <b>Next step status</b>: If any callout installed on "lease6_decline"
+ sets the status to SKIP, the server will not decline the lease, but will
+ continue processing the packet as if it did. It will send the response
+ that the lease was declined, but the actual database will not be
+ updated. If any callout installed sets the status to DROP, the packet
+ processing will be aborted, the lease will not be declined and the
+ server will not send a response.
+
@subsection dhcpv6HooksLease6Release lease6_release
- @b Arguments:
The argument includes the client and transaction identification
information.
+% DHCP6_HOOK_DECLINE_SKIP During Decline processing (client=%1, interface=%2, addr=%3) hook callout set status to DROP, ignoring packet.
+This message indicates that the server received DECLINE message, it was verified
+to be correct and matching server's lease information. The server called hooks
+for the lease6_decline hook point and one of the callouts set next step status to SKIP.
+The server will skip the operation of moving the lease to the declined state and
+will continue processing.
+
+% DHCP6_HOOK_DECLINE_DROP During Decline processing (client=%1, interface=%2, addr=%3) hook callout set status to DROP, dropping packet.
+This message indicates that the server received DECLINE message, it was verified
+to be correct and matching server's lease information. The server called hooks
+for the lease6_decline hook point and one of the callouts set next step status to DROP.
+The server will now abort processing of the packet as if it was never
+received. The lease will continue to be assigned to this client.
+
% DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP %1: DHCPv6 address lease was not released because a callout set the skip flag
This debug message is printed when a callout installed on the
lease6_release hook point set the skip flag. For this particular hook
int hook_index_lease6_release_; ///< index for "lease6_release" hook point
int hook_index_pkt6_send_; ///< index for "pkt6_send" hook point
int hook_index_buffer6_send_; ///< index for "buffer6_send" hook point
+ int hook_index_lease6_decline_; ///< index for "lease6_decline" hook point
/// Constructor that registers hook points for DHCPv6 engine
Dhcp6Hooks() {
hook_index_lease6_release_ = HooksManager::registerHook("lease6_release");
hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send");
hook_index_buffer6_send_ = HooksManager::registerHook("buffer6_send");
+ hook_index_lease6_decline_ = HooksManager::registerHook("lease6_decline");
}
};
// Include server-id
appendDefaultOptions(decline, reply);
- declineLeases(decline, reply, ctx);
+ if (declineLeases(decline, reply, ctx)) {
+ return (reply);
+ } else {
- return (reply);
+ // declineLeases returns false only if the hooks set the next step
+ // status to DROP. We'll just doing as requested.
+ return (Pkt6Ptr());
+ }
}
-void
+bool
Dhcpv6Srv::declineLeases(const Pkt6Ptr& decline, Pkt6Ptr& reply,
AllocEngine::ClientContext6& ctx) {
OptionPtr answer_opt = declineIA(decline, ctx.duid_, general_status,
boost::dynamic_pointer_cast<Option6IA>(opt->second));
if (answer_opt) {
+
+ // We have an answer, let's use it.
reply->addOption(answer_opt);
+ } else {
+
+ // The only case when declineIA could return NULL is if one of the
+ // hook callouts set next step status to DROP. We just need to drop
+ // this packet.
+ return (false);
}
break;
}
;
}
}
+
+ return (true);
}
OptionPtr
}
// Ok, all is good. Decline this lease.
- declineLease(decline, lease, ia_rsp);
+ if (!declineLease(decline, lease, ia_rsp)) {
+ // declineLease returns false only when hook callouts set the next
+ // step status to drop. We just propagate the bad news here.
+ return (OptionPtr());
+ }
}
if (total_addrs == 0) {
container->addOption(status);
}
-void
+bool
Dhcpv6Srv::declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
boost::shared_ptr<Option6IA> ia_rsp) {
+ // Let's call lease6_decline hooks if necessary.
+ if (HooksManager::calloutsPresent(Hooks.hook_index_lease6_decline_)) {
+ CalloutHandlePtr callout_handle = getCalloutHandle(decline);
+
+ // Delete previously set arguments
+ callout_handle->deleteAllArguments();
+
+ // Pass incoming packet as argument
+ callout_handle->setArgument("query6", decline);
+ callout_handle->setArgument("lease6", lease);
+
+ // Call callouts
+ HooksManager::callCallouts(Hooks.hook_index_lease6_decline_,
+ *callout_handle);
+
+ // Callouts decided to SKIP the next processing step. The next
+ // processing step would to actually decline the lease, so we'll
+ // keep the lease as is.
+ if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
+ LOG_DEBUG(hooks_logger, DBG_DHCP6_DETAIL, DHCP6_HOOK_DECLINE_SKIP)
+ .arg(decline->getLabel())
+ .arg(decline->getIface())
+ .arg(lease->addr_.toText());
+ return (true);
+ }
+
+ // Callouts decided to DROP the packet. Let's simply log it and
+ // return false, so upper layers will act accordingly.
+ if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_DROP) {
+ LOG_DEBUG(hooks_logger, DBG_DHCP6_DETAIL, DHCP6_HOOK_DECLINE_DROP)
+ .arg(decline->getLabel())
+ .arg(decline->getIface())
+ .arg(lease->addr_.toText());
+ return (false);
+ }
+ }
+
// Check if a lease has flags indicating that the FQDN update has
// been performed. If so, create NameChangeRequest which removes
// the entries. This method does all necessary checks.
// Global declined addresses counter.
StatsMgr::instance().addValue("declined-addresses", static_cast<int64_t>(1));
- // @todo: Call hooks.
-
// We need to disassociate the lease from the client. Once we move a lease
// to declined state, it is no longer associated with the client in any
// way.
ia_rsp->addOption(createStatusCode(*decline, *ia_rsp, STATUS_Success,
"Lease declined. Hopefully the next one will be better."));
+
+ return (true);
}
Pkt6Ptr
/// @param decline Decline messege sent by a client
/// @param reply Server's response (IA_NA with status will be added here)
/// @param client context
- void
- declineLeases(const Pkt6Ptr& decline, Pkt6Ptr& reply,
- AllocEngine::ClientContext6& ctx);
+ /// @return true when expected to continue, false when hooks told us to drop
+ /// the packet
+ bool declineLeases(const Pkt6Ptr& decline, Pkt6Ptr& reply,
+ AllocEngine::ClientContext6& ctx);
/// @brief Declines leases in a single IA_NA option
///
/// @param decline used for generating removal Name Change Request.
/// @param lease lease to be declined
/// @param ia_rsp response IA_NA.
- void
- declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
- boost::shared_ptr<Option6IA> ia_rsp);
+ /// @return true when expected to continue, false when hooks told us to drop
+ /// the packet
+ bool declineLease(const Pkt6Ptr& decline, const Lease6Ptr lease,
+ boost::shared_ptr<Option6IA> ia_rsp);
/// @brief A simple utility method that sets the status code
///
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp6/json_config_parser.h>
#include <dhcp6/tests/dhcp6_message_test.h>
+#include <dhcpsrv/lease.h>
#include <stats/stats_mgr.h>
using namespace isc;
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
using namespace isc::stats;
namespace {
class DeclineTest : public Dhcpv6MessageTest {
public:
- /// @brief Specifies expected outcome
- enum ExpectedResult {
- SHOULD_PASS, // pass = accept decline, move lease to declined state.
- SHOULD_FAIL // fail = reject the decline
- };
-
- /// @brief Specifies what address should the client include in its Decline
- enum AddressInclusion {
- VALID_ADDR, // Client will include its own, valid address
- BOGUS_ADDR, // Client will include an address it doesn't own
- NO_ADDR, // Client will send empty IA_NA (without address)
- NO_IA // Client will not send IA_NA at all
- };
-
- /// @brief Tests if the acquired lease is or is not declined.
- ///
- /// @param duid1 DUID used during lease acquisition
- /// @param iaid1 IAID used during lease acquisition
- /// @param duid2 DUID used during Decline exchange
- /// @param iaid2 IAID used during Decline exchange
- /// @param addr_type specify what sort of address the client should
- /// include (its own, a bogus one or no address at all)
- /// @param expected_result SHOULD_PASS if the lease is expected to
- /// be successfully declined, or SHOULD_FAIL if the lease is expected
- /// to not be declined.
- void acquireAndDecline(const std::string& duid1,
- const uint32_t iaid1,
- const std::string& duid2,
- const uint32_t iaid2,
- AddressInclusion addr_type,
- ExpectedResult expected_result);
-
/// @brief Constructor.
///
/// Sets up fake interfaces.
};
+};
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
void
-DeclineTest::acquireAndDecline(const std::string& duid1,
- const uint32_t iaid1,
- const std::string& duid2,
- const uint32_t iaid2,
- AddressInclusion addr_type,
- ExpectedResult expected_result) {
+Dhcpv6SrvTest::acquireAndDecline(Dhcp6Client& client,
+ const std::string& duid1,
+ const uint32_t iaid1,
+ const std::string& duid2,
+ const uint32_t iaid2,
+ AddressInclusion addr_type,
+ ExpectedResult expected_result) {
// Set this global statistic explicitly to zero.
StatsMgr::instance().setValue("declined-addresses", static_cast<int64_t>(0));
- Dhcp6Client client;
client.setDUID(duid1);
client.useNA(iaid1);
// Make sure that the client has acquired NA lease.
std::vector<Lease6> leases_client_na = client.getLeasesByType(Lease::TYPE_NA);
ASSERT_EQ(1, leases_client_na.size());
- EXPECT_EQ(STATUS_Success, client.getStatusCode(na_iaid_));
+ EXPECT_EQ(STATUS_Success, client.getStatusCode(iaid1));
// Remember the acquired address.
IOAddress acquired_address = leases_client_na[0].addr_;
// This test checks that the client can acquire and decline the lease.
TEST_F(DeclineTest, basic) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
- "01:02:03:04:05:06", 1234,
- VALID_ADDR, SHOULD_PASS);
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1234, VALID_ADDR, SHOULD_PASS);
}
+};
+};
+};
+
+namespace {
+
// This test verifies the decline is rejected in the following case:
// - Client acquires new lease using duid, iaid
// - Client sends the DECLINE with duid, iaid, but uses wrong address.
// - The server rejects Decline due to address mismatch
TEST_F(DeclineTest, addressMismatch) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
- "01:02:03:04:05:06", 1234,
- BOGUS_ADDR, SHOULD_FAIL);
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1234, BOGUS_ADDR, SHOULD_FAIL);
}
// This test verifies the decline is rejected in the following case:
// - Client sends the DECLINE with duid, iaid2
// - The server rejects Decline due to IAID mismatch
TEST_F(DeclineTest, iaidMismatch) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
- "01:02:03:04:05:06", 1235,
- VALID_ADDR, SHOULD_FAIL);
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1235, VALID_ADDR, SHOULD_FAIL);
}
// This test verifies the decline correctness in the following case:
// - Client sends the DECLINE using duid2, iaid
// - The server rejects the Decline due to DUID mismatch
TEST_F(DeclineTest, duidMismatch) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234,
"01:02:03:04:05:07", 1234,
VALID_ADDR, SHOULD_FAIL);
}
// include the address in it
// - The server rejects the Decline due to missing address
TEST_F(DeclineTest, noAddrsSent) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234,
"01:02:03:04:05:06", 1234,
NO_ADDR, SHOULD_FAIL);
}
// include IA_NA at all
// - The server rejects the Decline due to missing IA_NA
TEST_F(DeclineTest, noIAs) {
- acquireAndDecline("01:02:03:04:05:06", 1234,
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234,
"01:02:03:04:05:06", 1234,
NO_IA, SHOULD_FAIL);
}
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
/// - not relayed
///
/// @param srv Object representing server under test.
- Dhcp6Client(boost::shared_ptr<isc::test::NakedDhcpv6Srv>& srv);
+ Dhcp6Client(boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv>& srv);
/// @brief Create lease for the client.
///
}
/// @brief Returns the server that the client is communicating with.
- boost::shared_ptr<isc::test::NakedDhcpv6Srv> getServer() const {
+ boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv> getServer() const {
return (srv_);
}
std::string iface_name_;
/// @brief Pointer to the server that the client is communicating with.
- boost::shared_ptr<isc::test::NakedDhcpv6Srv> srv_;
+ boost::shared_ptr<isc::dhcp::test::NakedDhcpv6Srv> srv_;
bool use_na_; ///< Enable address assignment.
bool use_pd_; ///< Enable prefix delegation.
-// Copyright (C) 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
/// @brief Base class for test fixure classes used to validate the DHCPv6
/// message processing by the server.
-class Dhcpv6MessageTest : public isc::test::Dhcpv6SrvTest {
+class Dhcpv6MessageTest : public isc::dhcp::test::Dhcpv6SrvTest {
public:
/// @brief Constructor.
///
using namespace isc;
using namespace isc::data;
-using namespace isc::test;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
using namespace isc::stats;
namespace isc {
+namespace dhcp {
namespace test {
const char* NakedDhcpv6SrvTest::DUID_FILE = "server-id-test.txt";
}
}
-
-}; // end of isc::test namespace
+}; // end of isc::dhcp::test namespace
+}; // end of isc::dhcp namespace
}; // end of isc namespace
#include <list>
namespace isc {
+namespace dhcp {
namespace test {
/// @brief "naked" Dhcpv6Srv class that exposes internal members
std::string valid_iface_;
};
+// We need to pass one reference to the Dhcp6Client, which is defined in
+// dhcp6_client.h. That header includes this file. To avoid circular
+// dependencies, we use forward declaration here.
+class Dhcp6Client;
+
// Provides suport for tests against a preconfigured subnet6
// extends upon NakedDhcp6SrvTest
class Dhcpv6SrvTest : public NakedDhcpv6SrvTest {
public:
- /// Name of the server-id file (used in server-id tests)
+ /// @brief Specifies expected outcome
+ enum ExpectedResult {
+ SHOULD_PASS, // pass = accept decline, move lease to declined state.
+ SHOULD_FAIL // fail = reject the decline
+ };
+
+ /// @brief Specifies what address should the client include in its Decline
+ enum AddressInclusion {
+ VALID_ADDR, // Client will include its own, valid address
+ BOGUS_ADDR, // Client will include an address it doesn't own
+ NO_ADDR, // Client will send empty IA_NA (without address)
+ NO_IA // Client will not send IA_NA at all
+ };
/// @brief Constructor that initializes a simple default configuration
///
bool compareOptions(const isc::dhcp::OptionPtr& option1,
const isc::dhcp::OptionPtr& option2);
+ /// @brief Tests if the acquired lease is or is not declined.
+ ///
+ /// @param client Dhcp6Client instance
+ /// @param duid1 DUID used during lease acquisition
+ /// @param iaid1 IAID used during lease acquisition
+ /// @param duid2 DUID used during Decline exchange
+ /// @param iaid2 IAID used during Decline exchange
+ /// @param addr_type specify what sort of address the client should
+ /// include (its own, a bogus one or no address at all)
+ /// @param expected_result SHOULD_PASS if the lease is expected to
+ /// be successfully declined, or SHOULD_FAIL if the lease is expected
+ /// to not be declined.
+ void acquireAndDecline(Dhcp6Client& client,
+ const std::string& duid1,
+ const uint32_t iaid1,
+ const std::string& duid2,
+ const uint32_t iaid2,
+ AddressInclusion addr_type,
+ ExpectedResult expected_result);
+
/// @brief Performs basic (positive) RENEW test
///
/// See renewBasic and pdRenewBasic tests for detailed explanation.
NakedDhcpv6Srv srv_;
};
-}; // end of isc::test namespace
+}; // end of isc::dhcp::test namespace
+}; // end of isc::dhcp namespace
}; // end of isc namespace
#endif // DHCP6_TEST_UTILS_H
#include <gtest/gtest.h>
using namespace isc;
-using namespace isc::test;
+using namespace isc::dhcp::test;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp_ddns;
#include <hooks/server_hooks.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
+#include <dhcp6/tests/dhcp6_client.h>
#include <dhcp/tests/pkt_captures.h>
#include <cc/command_interpreter.h>
#include <boost/scoped_ptr.hpp>
using namespace isc;
using namespace isc::data;
-using namespace isc::test;
+using namespace isc::dhcp::test;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::util;
return (0);
}
+ /// Lease6_decline test callback
+ ///
+ /// Stores all parameters in callback_* fields.
+ ///
+ /// @param callout_handle handle passed by the hooks framework
+ /// @return always 0
+ static int
+ lease6_decline_callout(CalloutHandle& callout_handle) {
+ callback_name_ = string("lease6_decline");
+ callout_handle.getArgument("query6", callback_pkt6_);
+ callout_handle.getArgument("lease6", callback_lease6_);
+
+ return (0);
+ }
+
+ /// Lease6_decline callout that sets status to SKIP
+ ///
+ /// @param callout_handle handle passed by the hooks framework
+ /// @return always 0
+ static int
+ lease6_decline_skip_callout(CalloutHandle& callout_handle) {
+ callout_handle.setStatus(CalloutHandle::NEXT_STEP_SKIP);
+
+ return (lease6_decline_callout(callout_handle));
+ }
+
+ /// Lease6_decline callout that sets status to DROP
+ ///
+ /// @param callout_handle handle passed by the hooks framework
+ /// @return always 0
+ static int
+ lease6_decline_drop_callout(CalloutHandle& callout_handle) {
+ callout_handle.setStatus(CalloutHandle::NEXT_STEP_DROP);
+
+ return (lease6_decline_callout(callout_handle));
+ }
+
/// Resets buffers used to store data received by callouts
void resetCalloutBuffers() {
callback_name_ = string("");
ASSERT_TRUE(l);
}
+// This test checks that the basic decline hook (lease6_decline) is
+// triggered properly.
+TEST_F(HooksDhcpv6SrvTest, declineBasic) {
+
+ // Install lease6_decline callout
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "lease6_decline", lease6_decline_callout));
+
+ // Get an address and decline it. DUIDs, IAID match and we send valid
+ // address, so the decline procedure should be successful.
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1234, VALID_ADDR, SHOULD_PASS);
+
+ // Check that the proper callback was called.
+ EXPECT_EQ("lease6_decline", callback_name_);
+
+ // And valid parameters were passed.
+ ASSERT_TRUE(callback_pkt6_);
+ ASSERT_TRUE(callback_lease6_);
+
+ // Test sanity check - it was a decline, right?
+ EXPECT_EQ(DHCPV6_DECLINE, callback_pkt6_->getType());
+
+ // Get the address from this decline.
+ OptionPtr ia = callback_pkt6_->getOption(D6O_IA_NA);
+ ASSERT_TRUE(ia);
+ boost::shared_ptr<Option6IAAddr> addr_opt =
+ boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(D6O_IAADDR));
+ ASSERT_TRUE(addr_opt);
+ IOAddress addr(addr_opt->getAddress());
+
+ // Now get a lease from the database.
+ Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr);
+ ASSERT_TRUE(from_mgr);
+ // Now check that it's indeed declined.
+ EXPECT_EQ(Lease::STATE_DECLINED, from_mgr->state_);
+
+ // And that the parameters passed to callout are consistent with the database
+ EXPECT_EQ(addr, from_mgr->addr_);
+ EXPECT_EQ(addr, callback_lease6_->addr_);
+}
+
+// Test that the lease6_decline hook point can handle SKIP status.
+TEST_F(HooksDhcpv6SrvTest, declineSkip) {
+ // Install lease6_decline callout. It will set the status to skip
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "lease6_decline", lease6_decline_skip_callout));
+
+ // Get an address and decline it. DUIDs, IAID match and we send valid
+ // address, so the decline procedure should be successful.
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1234, VALID_ADDR, SHOULD_FAIL);
+
+ // Check that the proper callback was called.
+ EXPECT_EQ("lease6_decline", callback_name_);
+
+ // And valid parameters were passed.
+ ASSERT_TRUE(callback_pkt6_);
+ ASSERT_TRUE(callback_lease6_);
+
+ // Test sanity check - it was a decline, right?
+ EXPECT_EQ(DHCPV6_DECLINE, callback_pkt6_->getType());
+
+ // Get the address from this decline.
+ OptionPtr ia = callback_pkt6_->getOption(D6O_IA_NA);
+ ASSERT_TRUE(ia);
+ boost::shared_ptr<Option6IAAddr> addr_opt =
+ boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(D6O_IAADDR));
+ ASSERT_TRUE(addr_opt);
+ IOAddress addr(addr_opt->getAddress());
+
+ // Now get a lease from the database.
+ Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr);
+ ASSERT_TRUE(from_mgr);
+ // Now check that it's NOT declined.
+ EXPECT_EQ(Lease::STATE_DEFAULT, from_mgr->state_);
+
+ // And that the parameters passed to callout are consistent with the database
+ EXPECT_EQ(addr, from_mgr->addr_);
+ EXPECT_EQ(addr, callback_lease6_->addr_);
+}
+
+// Test that the lease6_decline hook point can handle DROP status.
+TEST_F(HooksDhcpv6SrvTest, declineDrop) {
+ // Install lease6_decline callout. It will set the status to skip
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "lease6_decline", lease6_decline_drop_callout));
+
+ // Get an address and decline it. DUIDs, IAID match and we send valid
+ // address, so it would work, but the callout sets status to DROP, so
+ // the server should not update the lease and should not send back any
+ // packets.
+ Dhcp6Client client;
+ acquireAndDecline(client, "01:02:03:04:05:06", 1234, "01:02:03:04:05:06",
+ 1234, VALID_ADDR, SHOULD_FAIL);
+
+ // Check that the proper callback was called.
+ EXPECT_EQ("lease6_decline", callback_name_);
+
+ // And valid parameters were passed.
+ ASSERT_TRUE(callback_pkt6_);
+ ASSERT_TRUE(callback_lease6_);
+
+ // Test sanity check - it was a decline, right?
+ EXPECT_EQ(DHCPV6_DECLINE, callback_pkt6_->getType());
+
+ // Get the address from this decline.
+ OptionPtr ia = callback_pkt6_->getOption(D6O_IA_NA);
+ ASSERT_TRUE(ia);
+ boost::shared_ptr<Option6IAAddr> addr_opt =
+ boost::dynamic_pointer_cast<Option6IAAddr>(ia->getOption(D6O_IAADDR));
+ ASSERT_TRUE(addr_opt);
+ IOAddress addr(addr_opt->getAddress());
+
+ // Now get a lease from the database.
+ Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
+ addr);
+ ASSERT_TRUE(from_mgr);
+ // Now check that it's NOT declined.
+ EXPECT_EQ(Lease::STATE_DEFAULT, from_mgr->state_);
+}
+
} // end of anonymous namespace
using namespace isc;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
using namespace isc;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
using namespace isc;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
-using namespace isc::test;
namespace {
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::dhcp::test;
using boost::scoped_ptr;
namespace {
// Let's use a captured traffic. The one we have comes from a
// modem with MAC address 10:0d:7f:00:07:88.
- Pkt6Ptr pkt = isc::test::PktCaptures::captureDocsisRelayedSolicit();
+ Pkt6Ptr pkt = PktCaptures::captureDocsisRelayedSolicit();
ASSERT_NO_THROW(pkt->unpack());
// The method should return MAC based on the vendor-specific info,
// Let's use a captured traffic. The one we have comes from a
// modem with MAC address 20:e5:2a:b8:15:14.
- Pkt6Ptr pkt = isc::test::PktCaptures::captureeRouterRelayedSolicit();
+ Pkt6Ptr pkt = PktCaptures::captureeRouterRelayedSolicit();
ASSERT_NO_THROW(pkt->unpack());
// The method should return MAC based on the vendor-specific info,
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
+#ifndef PKT_CAPTURES_H
+#define PKT_CAPTURES_H
+
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
namespace isc {
+namespace dhcp {
namespace test {
class PktCaptures {
static void captureSetDefaultFields(const isc::dhcp::Pkt4Ptr& pkt);
};
-};
-};
+}; // end of namespace isc::dhcp::test
+}; // end of namespace isc::dhcp
+}; // end of namespace isc
+
+#endif
using namespace isc::asiolink;
namespace isc {
+namespace dhcp {
namespace test {
Pkt4Ptr PktCaptures::packetFromCapture(const std::string& hex_string) {
return (packetFromCapture(hex_string));
}
-}; // end of isc::test namespace
+}; // end of isc::dhcp::test namespace
+}; // end of isc::dhcp namespace
}; // end of isc namespace
using namespace std;
namespace isc {
+namespace dhcp {
namespace test {
void PktCaptures::captureSetDefaultFields(const Pkt6Ptr& pkt) {
}
/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 cable modem)
-Pkt6Ptr isc::test::PktCaptures::captureDocsisRelayedSolicit() {
+Pkt6Ptr PktCaptures::captureDocsisRelayedSolicit() {
// This is an actual DOCSIS packet
// RELAY-FORW (12)
}
/// returns a buffer with relayed SOLICIT (from DOCSIS3.0 eRouter)
-Pkt6Ptr isc::test::PktCaptures::captureeRouterRelayedSolicit() {
+Pkt6Ptr PktCaptures::captureeRouterRelayedSolicit() {
/* Packet description exported from wireshark:
DHCPv6
return (pkt);
}
-Pkt6Ptr isc::test::PktCaptures::captureCableLabsShortVendorClass() {
+Pkt6Ptr PktCaptures::captureCableLabsShortVendorClass() {
// This is a simple non-relayed Solicit:
// - client-identifier
// - IA_NA
/// The original capture was posted to dibbler users mailing list.
///
/// @return created double relayed SOLICIT message
-isc::dhcp::Pkt6Ptr isc::test::PktCaptures::captureRelayed2xRSOO() {
+isc::dhcp::Pkt6Ptr PktCaptures::captureRelayed2xRSOO() {
// string exported from Wireshark
string hex_string =
return (pkt);
}
-
-}; // end of isc::test namespace
+}; // end of isc::dhcp::test namespace
+}; // end of isc::dhcp namespace
}; // end of isc namespace