Commit d9180390 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[4206] Unit-tests implemented for empty duid/client-id.

parent b718b770
......@@ -212,6 +212,17 @@ Dhcp4Client::createMsg(const uint8_t msg_type) {
return (msg);
}
void
Dhcp4Client::appendExtraOptions() {
// If there are any custom options specified, add them all to the message.
if (!extra_options_.empty()) {
for (OptionCollection::iterator opt = extra_options_.begin();
opt != extra_options_.end(); ++opt) {
context_.query_->addOption(opt->second);
}
}
}
void
Dhcp4Client::doDiscover(const boost::shared_ptr<IOAddress>& requested_addr) {
context_.query_ = createMsg(DHCPDISCOVER);
......@@ -228,6 +239,8 @@ Dhcp4Client::doDiscover(const boost::shared_ptr<IOAddress>& requested_addr) {
if (ciaddr_.isSpecified()) {
context_.query_->setCiaddr(ciaddr_.get());
}
appendExtraOptions();
// Send the message to the server.
sendMsg(context_.query_);
// Expect response.
......@@ -485,6 +498,11 @@ Dhcp4Client::setHWAddress(const std::string& hwaddr_str) {
}
}
void
Dhcp4Client::addExtraOption(const OptionPtr& opt) {
extra_options_.insert(std::make_pair(opt->getType(), opt));
}
} // end of namespace isc::dhcp::test
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -355,7 +355,16 @@ public:
/// in the client's messages.
isc::util::OptionalValue<asiolink::IOAddress> ciaddr_;
/// @brief Adds extra option (an option the client will always send)
///
/// @param opt additional option to be sent
void addExtraOption(const OptionPtr& opt);
private:
/// @brief Appends extra options, previously added with addExtraOption()
///
/// @brief Copies options from extra_options_ into outgoing message
void appendExtraOptions();
/// @brief Creates and adds Requested IP Address option to the client's
/// query.
......@@ -467,6 +476,8 @@ private:
/// @brief Enable relaying messages to the server.
bool use_relay_;
/// @brief Extra options the client will send.
OptionCollection extra_options_;
};
} // end of namespace isc::dhcp::test
......
......@@ -19,6 +19,7 @@
#include <cc/command_interpreter.h>
#include <config/command_mgr.h>
#include <dhcp4/tests/dhcp4_test_utils.h>
#include <dhcp4/tests/dhcp4_client.h>
#include <dhcp/tests/pkt_captures.h>
#include <dhcp/dhcp4.h>
#include <dhcp/iface_mgr.h>
......@@ -2659,6 +2660,29 @@ TEST_F(Dhcpv4SrvTest, statisticsUnknownRcvd) {
EXPECT_EQ(1, drop_stat->getInteger().first);
}
// This test verifies that the server is able to handle an empty client-id
// in incoming client message.
TEST_F(Dhcpv4SrvTest, emptyClientId) {
Dhcp4Client client;
EXPECT_NO_THROW(configure(CONFIGS[0], *client.getServer()));
// Tell the client to not send client-id on its own.
client.includeClientId("");
// Instead, tell him to send this extra option, which happens to be
// an empty client-id.
OptionPtr empty_client_id(new Option(Option::V4, DHO_DHCP_CLIENT_IDENTIFIER));
client.addExtraOption(empty_client_id);
// Let's check whether the server is able to process this packet without
// throwing any exceptions. We don't care whether the server sent any
// responses or not. The goal is to check that the server didn't throw
// any exceptions.
EXPECT_NO_THROW(client.doDORA());
}
/// @todo: Implement proper tests for MySQL lease/host database,
/// see ticket #4214.
......
......@@ -369,6 +369,7 @@ Dhcp6Client::createMsg(const uint8_t msg_type) {
if (use_client_id_) {
msg->addOption(getClientId());
}
if (use_oro_) {
OptionUint16ArrayPtr oro(new OptionUint16Array(Option::V6, D6O_ORO));
oro->setValues(oro_);
......@@ -376,6 +377,14 @@ Dhcp6Client::createMsg(const uint8_t msg_type) {
msg->addOption(oro);
};
// If there are any custom options specified, add them all to the message.
if (!extra_options_.empty()) {
for (OptionCollection::iterator opt = extra_options_.begin();
opt != extra_options_.end(); ++opt) {
msg->addOption(opt->second);
}
}
return (msg);
}
......@@ -758,7 +767,10 @@ Dhcp6Client::useFQDN(const uint8_t flags, const std::string& fqdn_name,
fqdn_.reset(new Option6ClientFqdn(flags, fqdn_name, fqdn_type));
}
void
Dhcp6Client::addExtraOption(const OptionPtr& opt) {
extra_options_.insert(std::make_pair(opt->getType(), opt));
}
} // end of namespace isc::dhcp::test
} // end of namespace isc::dhcp
......
......@@ -579,6 +579,11 @@ public:
void
generateIAFromLeases(const Pkt6Ptr& query);
/// @brief Adds extra option (an option the client will always send)
///
/// @param opt additional option to be sent
void addExtraOption(const OptionPtr& opt);
private:
/// @brief Applies the new leases for the client.
......@@ -752,6 +757,9 @@ private:
/// @brief forced (Overridden) value of the server-id option (may be NULL)
OptionPtr forced_server_id_;
/// @brief Extra options the client will send.
OptionCollection extra_options_;
/// @brief FQDN requested by the client.
Option6ClientFqdnPtr fqdn_;
......
......@@ -2734,6 +2734,77 @@ TEST_F(Dhcpv6SrvTest, receiveParseFailedStat) {
EXPECT_EQ(1, recv_drop->getInteger().first);
}
// This test verifies that the server is able to handle an empty DUID (client-id)
// in incoming client message.
TEST_F(Dhcpv6SrvTest, emptyClientId) {
Dhcp6Client client;
// The following configuration enables RSOO options: 110 and 120.
// It also configures the server with option 120 which should
// "override" the option 120 sent in the RSOO by the relay.
string config =
"{"
" \"preferred-lifetime\": 3000,"
" \"rebind-timer\": 2000, "
" \"renew-timer\": 1000, "
" \"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
" \"subnet\": \"2001:db8::/48\" "
" } ],"
" \"valid-lifetime\": 4000"
"}";
EXPECT_NO_THROW(configure(config, *client.getServer()));
// Tell the client to not send client-id on its own.
client.useClientId(false);
// Instead, tell him to send this extra option, which happens to be
// an empty client-id.
OptionPtr empty_client_id(new Option(Option::V6, D6O_CLIENTID));
client.addExtraOption(empty_client_id);
// Let's check whether the server is able to process this packet without
// throwing any exceptions. We don't care whether the server sent any
// responses or not. The goal is to check that the server didn't throw
// any exceptions.
EXPECT_NO_THROW(client.doSARR());
}
// This test verifies that the server is able to handle an empty DUID (server-id)
// in incoming client message.
TEST_F(Dhcpv6SrvTest, emptyServerId) {
Dhcp6Client client;
// The following configuration enables RSOO options: 110 and 120.
// It also configures the server with option 120 which should
// "override" the option 120 sent in the RSOO by the relay.
string config =
"{"
" \"preferred-lifetime\": 3000,"
" \"rebind-timer\": 2000, "
" \"renew-timer\": 1000, "
" \"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8::/64\" } ],"
" \"subnet\": \"2001:db8::/48\" "
" } ],"
" \"valid-lifetime\": 4000"
"}";
EXPECT_NO_THROW(configure(config, *client.getServer()));
// Tell the client to use this specific server-id.
OptionPtr empty_server_id(new Option(Option::V6, D6O_SERVERID));
client.useServerId(empty_server_id);
// Let's check whether the server is able to process this packet without
// throwing any exceptions. We don't care whether the server sent any
// responses or not. The goal is to check that the server didn't throw
// any exceptions.
EXPECT_NO_THROW(client.doSARR());
}
/// @todo: Add more negative tests for processX(), e.g. extend sanityCheck() test
/// to call processX() methods.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment