BIND 10 trac3232, updated. 52bc81f617218678d89a061e790dfd1f09d6dd36 [3232] Addressed review comments.
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Mar 11 18:42:20 UTC 2014
The branch, trac3232 has been updated
via 52bc81f617218678d89a061e790dfd1f09d6dd36 (commit)
from 4593a9abb2ba1c6cc8c81fbe3ea95a2e3b6c7585 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 52bc81f617218678d89a061e790dfd1f09d6dd36
Author: Marcin Siodelski <marcin at isc.org>
Date: Tue Mar 11 19:42:06 2014 +0100
[3232] Addressed review comments.
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp6/tests/dhcp6_client.cc | 142 ++++++++++++++++++++------------
src/bin/dhcp6/tests/dhcp6_client.h | 86 +++++++++++++++++--
src/bin/dhcp6/tests/rebind_unittest.cc | 136 +++++++++++++++++++++++-------
src/lib/dhcp/option.h | 9 ++
4 files changed, 289 insertions(+), 84 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc
index ce51283..c1bad42 100644
--- a/src/bin/dhcp6/tests/dhcp6_client.cc
+++ b/src/bin/dhcp6/tests/dhcp6_client.cc
@@ -21,6 +21,7 @@
#include <dhcp6/tests/dhcp6_client.h>
#include <util/buffer.h>
#include <boost/pointer_cast.hpp>
+#include <cstdlib>
#include <time.h>
using namespace isc::test;
@@ -41,63 +42,99 @@ Dhcp6Client::Dhcp6Client() :
use_relay_(false) {
}
+Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
+ relay_link_addr_("3000:1::1"),
+ curr_transid_(0),
+ dest_addr_(ALL_DHCP_RELAY_AGENTS_AND_SERVERS),
+ duid_(generateDUID(DUID::DUID_LLT)),
+ link_local_("fe80::3a60:77ff:fed5:cdef"),
+ srv_(srv),
+ use_na_(false),
+ use_pd_(false),
+ use_relay_(false) {
+}
+
void
-Dhcp6Client::applyConfiguration(const Pkt6Ptr& reply) {
+Dhcp6Client::applyRcvdConfiguration(const Pkt6Ptr& reply) {
typedef OptionCollection Opts;
// Get all options in the reply message and pick IA_NA and IA_PD.
Opts opts = reply->options_;
for (Opts::const_iterator opt = opts.begin(); opt != opts.end(); ++opt) {
Option6IAPtr ia = boost::dynamic_pointer_cast<Option6IA>(opt->second);
- // If the current one is not IA option, get the next one.
if (!ia) {
continue;
}
- // The default value of the prefix length is 128 (as for IPv6 address),
- // as at this point we don't know if we are dealing with the address
- // of prefix.
- int prefix_len = 128;
- // Check if this is the address.
- Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<
- Option6IAAddr>(ia->getOption(D6O_IAADDR));
- // If this is not the address it may be a prefix.
- if (!iaaddr) {
- iaaddr = boost::dynamic_pointer_cast<
- Option6IAAddr>(ia->getOption(D6O_IAPREFIX));
- // If this is a prefix, modify the prefix length accordingly.
- if (iaaddr) {
- prefix_len = boost::dynamic_pointer_cast<
- Option6IAPrefix>(ia->getOption(D6O_IAPREFIX))->getLength();
+
+ const Opts& ia_opts = ia->getOptions();
+ for (Opts::const_iterator iter_ia_opt = ia_opts.begin();
+ iter_ia_opt != ia_opts.end(); ++iter_ia_opt) {
+ OptionPtr ia_opt = iter_ia_opt->second;
+ LeaseInfo lease_info;
+ switch (ia_opt->getType()) {
+ case D6O_IAADDR:
+ {
+ Option6IAAddrPtr iaaddr = boost::dynamic_pointer_cast<
+ Option6IAAddr>(ia->getOption(D6O_IAADDR));
+ if (!iaaddr) {
+ // There is no address. This IA option may simply
+ // contain a status code, so let's just reset the
+ // lease and keep IAID around.
+ lease_info.lease_ = Lease6();
+ lease_info.lease_.type_ = Lease::TYPE_NA;
+ lease_info.lease_.iaid_ = ia->getIAID();
+ break;
+ }
+ lease_info.lease_ = Lease6(Lease::TYPE_NA,
+ iaaddr->getAddress(),
+ duid_, ia->getIAID(),
+ iaaddr->getPreferred(),
+ iaaddr->getValid(),
+ ia->getT1(), ia->getT2(), 0);
+ lease_info.lease_.cltt_ = time(NULL);
+ }
+ break;
+
+ case D6O_IAPREFIX:
+ {
+ Option6IAPrefixPtr iaprefix = boost::dynamic_pointer_cast<
+ Option6IAPrefix>(ia->getOption(D6O_IAPREFIX));
+ if (!iaprefix) {
+ // There is no prefix. This IA option may simply
+ // contain a status code, so let's just reset the
+ // lease and keep IAID around.
+ lease_info.lease_ = Lease6();
+ lease_info.lease_.type_ = Lease::TYPE_PD;
+ lease_info.lease_.iaid_ = ia->getIAID();
+ break;
+ }
+ lease_info.lease_ = Lease6(Lease::TYPE_PD,
+ iaprefix->getAddress(), duid_,
+ ia->getIAID(),
+ iaprefix->getPreferred(),
+ iaprefix->getValid(),
+ ia->getT1(), ia->getT2(), 0,
+ iaprefix->getLength());
+ lease_info.lease_.cltt_ = time(NULL);
+ }
+ break;
+
+ case D6O_STATUS_CODE:
+ {
+ // Check if the server has sent status code. If no status
+ // code, assume the status code to be 0.
+ OptionCustomPtr status_code = boost::dynamic_pointer_cast<
+ OptionCustom>(ia->getOption(D6O_STATUS_CODE));
+ lease_info.status_code_ =
+ status_code ? status_code->readInteger<uint16_t>(0) : 0;
+ }
+ break;
+
+ default:
+ ; // no-op
}
- }
- /// Set the lease information if we have a prefix or address.
- LeaseInfo lease_info;
- if (iaaddr) {
- Lease6 lease((prefix_len == 128 ? Lease::TYPE_NA : Lease::TYPE_PD),
- iaaddr->getAddress(), duid_,
- ia->getIAID(), iaaddr->getPreferred(),
- iaaddr->getValid(), ia->getT1(), ia->getT2(), 0,
- prefix_len);
- lease.cltt_ = time(NULL);
-
- lease_info.lease_ = lease;
- } else {
- // There is no prefix and no address. This IA option may simply
- // contain a status code, so let's just reset the lease and keep
- // IAID around.
- lease_info.lease_ = Lease6();
- lease_info.lease_.iaid_ = ia->getIAID();
- }
- // Check if the server has sent status code. If no status code, assume
- // the status code to be 0.
- OptionCustomPtr status_code = boost::dynamic_pointer_cast<
- OptionCustom>(ia->getOption(D6O_STATUS_CODE));
- if (status_code) {
- lease_info.status_code_ = status_code->readInteger<uint16_t>(0);
- } else {
- lease_info.status_code_ = 0;
+ applyLease(lease_info);
}
- applyLease(lease_info);
}
}
@@ -111,6 +148,7 @@ Dhcp6Client::applyLease(const LeaseInfo& lease_info) {
// server hasn't sent the IA option. In this case, there is no
// lease assignment so we keep what we have.
if ((existing_lease.iaid_ == lease_info.lease_.iaid_)
+ && (existing_lease.type_ == lease_info.lease_.type_)
&& (lease_info.lease_.addr_ != asiolink::IOAddress("::"))) {
config_.leases_[i] = lease_info;
return;
@@ -218,7 +256,7 @@ Dhcp6Client::doRequest() {
// Apply new configuration only if the server has responded.
if (context_.response_) {
- applyConfiguration(context_.response_);
+ applyRcvdConfiguration(context_.response_);
}
}
@@ -231,7 +269,7 @@ Dhcp6Client::doRebind() {
context_.response_ = receiveOneMsg();
// Apply configuration only if the server has responded.
if (context_.response_) {
- applyConfiguration(context_.response_);
+ applyRcvdConfiguration(context_.response_);
}
}
@@ -253,7 +291,9 @@ Dhcp6Client::generateDUID(DUID::DUIDType duid_type) const {
" generation of DUID LLT");
}
duid.push_back(static_cast<uint8_t>(duid_type));
- duid.insert(duid.end(), 4, 0);
+ for (int i = 0; i < 4; ++i) {
+ duid.push_back(static_cast<uint8_t>(rand() % 255));
+ }
for (int i = 0; i < 6; ++i) {
duid.push_back(static_cast<uint8_t>(i));
}
@@ -319,6 +359,6 @@ Dhcp6Client::sendMsg(const Pkt6Ptr& msg) {
}
-}
-}
-}
+} // end of namespace isc::dhcp::test
+} // end of namespace isc::dhcp
+} // end of namespace isc
diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h
index b01c0f1..3ccf091 100644
--- a/src/bin/dhcp6/tests/dhcp6_client.h
+++ b/src/bin/dhcp6/tests/dhcp6_client.h
@@ -64,6 +64,10 @@ public:
/// @brief Holds the last status code that server has sent for
/// the particular lease.
uint16_t status_code_;
+
+ /// @brief Default constructor for the structure.
+ LeaseInfo() :
+ lease_(), status_code_(0) { }
};
/// @brief Holds the current client configuration obtained from the
@@ -85,9 +89,34 @@ public:
/// @brief Creates a new client.
///
- /// This constructor initializes the class members to default values.
+ /// This constructor initializes the class members to default values:
+ /// - relay link-addr = 3000:1::1
+ /// - first transaction id = 0
+ /// - dest-addr = All_DHCP_Relay_Agents_and_Servers
+ /// - duid (LLT) = <random 4 bytes>00010203040506
+ /// - link-local-addr = fe80::3a60:77ff:fed5:cdef
+ /// - IA_NA not requested
+ /// - IA_PD not requested
+ /// - not relayed
Dhcp6Client();
+ /// @brief Creates a new client that communicates with a specified server.
+ ///
+ /// This constructor allows passing a pointer to the server object which
+ /// should be used in a test. The server may be preconfigured before passed
+ /// to the constructor. The default configuration used by the client is:
+ /// - relay link-addr = 3000:1::1
+ /// - first transaction id = 0
+ /// - dest-addr = All_DHCP_Relay_Agents_and_Servers
+ /// - duid (LLT) = <random 4 bytes>00010203040506
+ /// - link-local-addr = fe80::3a60:77ff:fed5:cdef
+ /// - IA_NA not requested
+ /// - IA_PD not requested
+ /// - not relayed
+ ///
+ /// @param srv Object representing server under test.
+ Dhcp6Client(boost::shared_ptr<isc::test::NakedDhcpv6Srv>& srv);
+
/// @brief Performs a 4-way echange between the client and the server.
///
/// If the 4-way exchange is successful, the client should acquire leases
@@ -95,6 +124,12 @@ public:
/// that have been requested (IA_NA, IA_PD).
///
/// The leases acquired are accessible through the @c config_ member.
+ ///
+ /// @throw This function doesn't throw exceptions on its own, but it calls
+ /// functions that are not exception safe, so it may throw exceptions if
+ /// error occurs.
+ ///
+ /// @todo Perform sanity checks on returned messages.
void doSARR();
/// @brief Send Solicit and receive Advertise.
@@ -102,6 +137,12 @@ public:
/// This function simulates the first transaction of the 4-way exchange,
/// i.e. sends a Solicit to the server and receives Advertise. It doesn't
/// set the lease configuration in the @c config_.
+ ///
+ /// @throw This function doesn't throw exceptions on its own, but it calls
+ /// functions that are not exception safe, so it may throw exceptions if
+ /// error occurs.
+ ///
+ /// @todo Perform sanity checks on returned messages.
void doSolicit();
/// @brief Sends a Rebind to the server and receives the Reply.
@@ -111,6 +152,12 @@ public:
/// (either address or prefixes) and places them in the Rebind message.
/// If the server responds to the Rebind (and extends the lease lifetimes)
/// the current lease configuration is updated.
+ ///
+ /// @throw This function doesn't throw exceptions on its own, but it calls
+ /// functions that are not exception safe, so it may throw exceptions if
+ /// error occurs.
+ ///
+ /// @todo Perform sanity checks on returned messages.
void doRebind();
/// @brief Sends Request to the server and receives Reply.
@@ -120,6 +167,12 @@ public:
/// from the current context (server's Advertise) to request acquisition
/// of offered IAs. If the server responds to the Request (leases are
/// acquired) the client's lease configuration is updated.
+ ///
+ /// @throw This function doesn't throw exceptions on its own, but it calls
+ /// functions that are not exception safe, so it may throw exceptions if
+ /// error occurs.
+ ///
+ /// @todo Perform sanity checks on returned messages.
void doRequest();
/// @brief Simulates aging of leases by the specified number of seconds.
@@ -141,6 +194,10 @@ public:
/// @brief Returns lease at specified index.
///
+ /// @warning This method doesn't check if the specified index is out of
+ /// range. The caller is responsible for using a correct offset by
+ /// invoking the @c getLeaseNum function.
+ ///
/// @param at Index of the lease held by the client.
/// @return A lease at the specified index.
Lease6 getLease(const size_t at) const {
@@ -149,6 +206,10 @@ public:
/// @brief Returns status code set by the server for the lease.
///
+ /// @warning This method doesn't check if the specified index is out of
+ /// range. The caller is responsible for using a correct offset by
+ /// invoking the @c getLeaseNum function.
+ ///
/// @param at Index of the lease held by the client.
/// @return A status code for the lease at the specified index.
uint16_t getStatusCode(const size_t at) const {
@@ -215,8 +276,11 @@ public:
///
/// @param use Parameter which 'true' value indicates that client should
/// simulate sending messages via relay.
- void useRelay(const bool use = true) {
+ /// @param link_addr Relay link-addr.
+ void useRelay(const bool use = true,
+ const asiolink::IOAddress& link_addr = asiolink::IOAddress("3000:1::1")) {
use_relay_ = use;
+ relay_link_addr_ = link_addr;
}
/// @brief Lease configuration obtained by the client.
@@ -231,14 +295,20 @@ private:
///
/// This method is called when the client obtains a new configuration
/// from the server in the Reply message. This function adds new leases
- /// or replaces existing ones.
+ /// or replaces existing ones, on the client's side. Client uses these
+ /// leases in any later communication with the server when doing Renew
+ /// or Rebind.
///
/// @param reply Server response.
- void applyConfiguration(const Pkt6Ptr& reply);
+ ///
+ /// @todo Currently this function supports one IAAddr or IAPrefix option
+ /// within IA. We will need to extend it to support multiple options
+ /// within a single IA once server supports that.
+ void applyRcvdConfiguration(const Pkt6Ptr& reply);
/// @brief Applies configuration for the single lease.
///
- /// This method is called by the @c Dhcp6Client::applyConfiguration for
+ /// This method is called by the @c Dhcp6Client::applyRcvdConfiguration for
/// each individual lease.
///
/// @param lease_info Structure holding new lease information.
@@ -252,6 +322,8 @@ private:
///
/// @param source Message from which IA options will be copied.
/// @param dest Message to which IA options will be copied.
+ ///
+ /// @todo Add support for IA_TA.
void copyIAs(const Pkt6Ptr& source, const Pkt6Ptr& dest);
/// @brief Creates IA options from existing configuration.
@@ -283,6 +355,10 @@ private:
/// @brief Simulates sending a message to the server.
///
+ /// This function instantly triggers processing of the message by the
+ /// server. The server's response can be gathered by invoking the
+ /// @c receiveOneMsg function.
+ ///
/// @param msg Message to be sent.
void sendMsg(const Pkt6Ptr& msg);
diff --git a/src/bin/dhcp6/tests/rebind_unittest.cc b/src/bin/dhcp6/tests/rebind_unittest.cc
index 7aba0ba..de7e59b 100644
--- a/src/bin/dhcp6/tests/rebind_unittest.cc
+++ b/src/bin/dhcp6/tests/rebind_unittest.cc
@@ -29,7 +29,40 @@ using namespace isc::test;
namespace {
/// @brief Set of JSON configurations used throughout the Rebind tests.
-const std::string REBIND_CONFIGS[] = {
+///
+/// - Configuration 0:
+/// - only addresses (no prefixes)
+/// - 2 subnets with 2001:db8:1::/64 and 2001:db8:2::64
+/// - 1 subnet for eth0 and 1 subnet for eth1
+///
+/// - Configuration 1:
+/// - similar to Configuration 0 but different subnets
+/// - pools configured: 2001:db8:3::/64 and 2001:db8:4::/64
+///
+/// - Configuration 2:
+/// - similar to Configuration 0 and Configuration 1
+/// - pools configured: 3000:1::/64 and 3000:2::/64
+/// - this specific configuration is used by tests using relays
+///
+/// - Configuration 3:
+/// - similar to Configuration 2 but with different subnets
+/// - pools configured: 3000:3::/64 and 3000:4::/64
+/// - this specific configuration is used by tests using relays
+///
+/// - Configuration 5:
+/// - only prefixes (no addresses)
+/// - 2 subnets: 2001:db8:1::/40 and 2001:db8:2::/40
+/// - 2 prefix pools: 2001:db8:1::/72 and 2001:db8:2::/72
+/// - 1 subnet for eth0 and 1 subnet for eth1
+/// - this specific configuration is used by tests which don't use relays
+///
+/// - Configuration 6:
+/// - similar to Configuration 5 but with different subnets
+/// - 2 subnets: 2001:db8:3::/40 and 2001:db8:4::/40
+/// - 2 prefix pools: 2001:db8:3::/72 and 2001:db8:4::/72
+/// - delegated length /80
+/// - this specific configuration is used by tests which don't use relays
+const char* REBIND_CONFIGS[] = {
// Configuration 0
"{ \"interfaces\": [ \"all\" ],"
"\"preferred-lifetime\": 3000,"
@@ -112,25 +145,6 @@ const std::string REBIND_CONFIGS[] = {
"\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, "
"\"subnet6\": [ { "
- " \"pool\": [ \"3000:3::/64\" ],"
- " \"subnet\": \"3000:3::/48\", "
- " \"interface-id\": \"\","
- " \"interface\": \"eth1\""
- " },"
- " {"
- " \"pool\": [ \"3000:4::/64\" ],"
- " \"subnet\": \"3000:4::/48\", "
- " \"interface-id\": \"\","
- " \"interface\": \"eth0\""
- " } ],"
- "\"valid-lifetime\": 4000 }",
-
-// Configuration 5
- "{ \"interfaces\": [ \"all\" ],"
- "\"preferred-lifetime\": 3000,"
- "\"rebind-timer\": 2000, "
- "\"renew-timer\": 1000, "
- "\"subnet6\": [ { "
" \"pd-pools\": ["
" { \"prefix\": \"2001:db8:1:01::\", "
" \"prefix-len\": 72, "
@@ -152,7 +166,7 @@ const std::string REBIND_CONFIGS[] = {
" } ],"
"\"valid-lifetime\": 4000 }",
-// Configuration 6
+// Configuration 5
"{ \"interfaces\": [ \"all\" ],"
"\"preferred-lifetime\": 3000,"
"\"rebind-timer\": 2000, "
@@ -218,6 +232,8 @@ RebindTest::configure(const std::string& config, NakedDhcpv6Srv& srv) {
void
RebindTest::requestLease(const int config_index, const int subnets_num,
Dhcp6Client& client) {
+ // Check that the index is in the configuration table.
+ ASSERT_LT(config_index, sizeof(REBIND_CONFIGS)/sizeof(REBIND_CONFIGS[0]));
// Configure the server.
configure(REBIND_CONFIGS[config_index], *client.getServer());
// Make sure we ended-up having expected number of subnets configured.
@@ -241,6 +257,8 @@ RebindTest::requestLease(const int config_index, const int subnets_num,
EXPECT_EQ(STATUS_Success, client.getStatusCode(0));
}
+// Test that directly connected client's Rebind message is processed and Reply
+// message is sent back.
TEST_F(RebindTest, directClient) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -266,6 +284,8 @@ TEST_F(RebindTest, directClient) {
EXPECT_TRUE(lease_server2);
}
+// Test that server doesn't extend the lease when the configuration has changed
+// such that the existing subnet is replaced with a different subnet.
TEST_F(RebindTest, directClientChangingSubnet) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -298,6 +318,8 @@ TEST_F(RebindTest, directClientChangingSubnet) {
}
+// Check that the server doesn't extend the lease for the client when the
+// client sends IAID which doesn't belong to the lease that client has.
TEST_F(RebindTest, directClientChangingIAID) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -323,6 +345,8 @@ TEST_F(RebindTest, directClientChangingIAID) {
}
+// Check that server sends NoBinding when the lease has been lost from
+// the database and client is trying to Rebind it.
TEST_F(RebindTest, directClientLostLease) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -341,6 +365,9 @@ TEST_F(RebindTest, directClientLostLease) {
EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(0));
}
+/// @todo Extend tests for direct client changing address.
+
+// Check that the client can Rebind existing lease through a relay.
TEST_F(RebindTest, relayedClient) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -371,6 +398,9 @@ TEST_F(RebindTest, relayedClient) {
EXPECT_TRUE(lease_server2);
}
+// Check that the lease is not extended for the relayed client when the
+// configuration has changed such that the subnet that client is using
+// doesn't exist anymore.
TEST_F(RebindTest, relayedClientChangingSubnet) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -409,6 +439,8 @@ TEST_F(RebindTest, relayedClientChangingSubnet) {
}
+// Check that the lease is not extended for the relayed client when the IAID in
+// the Rebind message doesn't match the one recorded for the client.
TEST_F(RebindTest, relayedClientChangingIAID) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -438,6 +470,8 @@ TEST_F(RebindTest, relayedClientChangingIAID) {
}
+// Check that the relayed client receives NoBinding when the lease that he
+// is Rebinding has been lost from the database.
TEST_F(RebindTest, relayedClientLostLease) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -460,6 +494,8 @@ TEST_F(RebindTest, relayedClientLostLease) {
EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(0));
}
+// Check that relayed client receives the IA with lifetimes of 0, when
+// client is tgrying to Rebind using an address it doesn't have.
TEST_F(RebindTest, relayedClientChangingAddress) {
Dhcp6Client client;
// Configure client to request IA_NA.
@@ -497,13 +533,13 @@ TEST_F(RebindTest, relayedClientChangingAddress) {
EXPECT_NE(0, lease_server->preferred_lft_);
}
-
+// Check that the server extends the lease for the client having a prefix.
TEST_F(RebindTest, directClientPD) {
Dhcp6Client client;
// Configure client to request IA_PD.
client.usePD();
// Make 4-way exchange to get the lease.
- ASSERT_NO_FATAL_FAILURE(requestLease(5, 2, client));
+ ASSERT_NO_FATAL_FAILURE(requestLease(4, 2, client));
// Keep the client's lease for future reference.
Lease6 lease_client = client.getLease(0);
// Send Rebind message to the server.
@@ -523,18 +559,21 @@ TEST_F(RebindTest, directClientPD) {
EXPECT_TRUE(lease_server2);
}
+// Check that the prefix lifetime is not extended for the client in case
+// the configuration has been changed such, that the subnet he is using
+// doesn't exist anymore.
TEST_F(RebindTest, directClientPDChangingSubnet) {
Dhcp6Client client;
// Configure client to request IA_PD.
client.usePD();
// Make 4-way exchange to get the lease.
- ASSERT_NO_FATAL_FAILURE(requestLease(5, 2, client));
+ ASSERT_NO_FATAL_FAILURE(requestLease(4, 2, client));
// Keep the client's lease for future reference.
Lease6 lease_client = client.getLease(0);
// Reconfigure the server so as the new subnet is served on the
// client's interface. Note that there will also be a new subnet
// id assigned to the subnet on this interface.
- configure(REBIND_CONFIGS[6], *client.getServer());
+ configure(REBIND_CONFIGS[5], *client.getServer());
// Try to rebind, using the address that the client had acquired using
// previous server configuration.
ASSERT_NO_THROW(client.doRebind());
@@ -557,12 +596,15 @@ TEST_F(RebindTest, directClientPDChangingSubnet) {
EXPECT_TRUE(lease_server2);
}
+// Check that the prefix lifetime is not extended for the client when the
+// IAID used in the Rebind is not matching the one recorded by the server
+// for the particular client.
TEST_F(RebindTest, directClientPDChangingIAID) {
Dhcp6Client client;
// Configure client to request IA_PD.
client.usePD();
// Make 4-way exchange to get the lease.
- ASSERT_NO_FATAL_FAILURE(requestLease(5, 2, client));
+ ASSERT_NO_FATAL_FAILURE(requestLease(4, 2, client));
// Keep the client's lease for future reference.
Lease6 lease_client = client.getLease(0);
// Modify the IAID of the lease record that client stores. By adding
@@ -585,17 +627,21 @@ TEST_F(RebindTest, directClientPDChangingIAID) {
EXPECT_TRUE(lease_server);
}
+// Check that the prefix lifetime is not extended for the client when the
+// prefix used in Rebind message doesn't match the one that client has.
TEST_F(RebindTest, directClientPDChangingPrefix) {
Dhcp6Client client;
// Configure client to request IA_PD.
client.usePD();
// Make 4-way exchange to get the lease.
- ASSERT_NO_FATAL_FAILURE(requestLease(5, 2, client));
+ ASSERT_NO_FATAL_FAILURE(requestLease(4, 2, client));
// Keep the client's lease for future reference.
Lease6 lease_client = client.getLease(0);
// Modify the Prefix of the lease record that client stores. The server
// should check that the prefix is invalid (hasn't been allocated for
// the particular IAID).
+ ASSERT_NE(client.config_.leases_[0].lease_.addr_,
+ IOAddress("2001:db8:1:10::"));
client.config_.leases_[0].lease_.addr_ = IOAddress("2001:db8:1:10::");
// Try to Rebind. The client will use correct IAID but will specify a
// wrong prefix. The server will discover that the client has a binding
@@ -625,6 +671,7 @@ TEST_F(RebindTest, directClientPDChangingPrefix) {
}
/// @todo Extend PD tests for relayed messages.
+/// @todo Extend PD tests to cover same prefix buyt different length.
// This test checks that the Rebind message is discarded by the server if it
// has been sent to unicast address (RFC3315, section 15).
@@ -636,7 +683,7 @@ TEST_F(RebindTest, unicast) {
ASSERT_NO_FATAL_FAILURE(requestLease(0, 2, client));
// Keep the client's lease for future reference.
Lease6 lease_client = client.getLease(0);
- // Set the unicast destionation address for the Rebind message.
+ // Set the unicast destination address for the Rebind message.
// The Rebind should be discarded when sent to unicast address,
// according to section 15 of RFC3315.
client.setDestAddress(IOAddress("2001:db8:1::1"));
@@ -655,5 +702,38 @@ TEST_F(RebindTest, unicast) {
EXPECT_FALSE(client.getContext().response_);
}
+// This test checks that the relayed Rebind message is processed by the server
+// when sent to unicast address.
+TEST_F(RebindTest, relayedUnicast) {
+ Dhcp6Client client;
+ // Configure client to request IA_NA.
+ client.useNA();
+ // Configure DHCPv6 client to simulate sending the message through a relay
+ // agent. The default link-addr is 3001:1::1. This address should be used
+ // by the server to pick the suitable subnet.
+ client.useRelay();
+ // Make 4-way exchange to get the lease. Pick the configuration #2 as it
+ // specifies the subnet for the relay agent's link address.
+ ASSERT_NO_FATAL_FAILURE(requestLease(2, 2, client));
+ // Keep the client's lease for future reference.
+ Lease6 lease_client = client.getLease(0);
+ // Set the unicast destination address.
+ client.setDestAddress(IOAddress("2001:db8:1::1"));
+ // Send Rebind message to the server.
+ ASSERT_NO_THROW(client.doRebind());
+ // The client should still have one lease which belongs to one of the
+ // subnets.
+ ASSERT_EQ(1, client.getLeaseNum());
+ Lease6 lease_client2 = client.getLease(0);
+ ASSERT_TRUE(CfgMgr::instance().getSubnet6(lease_client2.addr_,
+ ClientClasses()));
+ // The client's lease should have been extended. The client will
+ // update the cltt to current time when the lease gets extended.
+ ASSERT_GE(lease_client2.cltt_ - lease_client.cltt_, 1000);
+ // Make sure, that the client's lease matches the lease held by the
+ // server.
+ Lease6Ptr lease_server2 = checkLease(lease_client2);
+ EXPECT_TRUE(lease_server2);
+}
} // end of anonymous namespace
diff --git a/src/lib/dhcp/option.h b/src/lib/dhcp/option.h
index dbdb3af..15390a2 100644
--- a/src/lib/dhcp/option.h
+++ b/src/lib/dhcp/option.h
@@ -254,6 +254,15 @@ public:
/// @return shared_ptr to requested suoption
OptionPtr getOption(uint16_t type);
+ /// @brief Returns all encapsulated options.
+ ///
+ /// @warning This function returns a reference to the container holding
+ /// encapsulated options, which is valid as long as the object which
+ /// returned it exists.
+ const OptionCollection& getOptions() const {
+ return (options_);
+ }
+
/// Attempts to delete first suboption of requested type
///
/// @param type Type of option to be deleted.
More information about the bind10-changes
mailing list