Commit ad411a17 authored by Marcin Siodelski's avatar Marcin Siodelski

[master] Merge branch 'trac3320'

parents 003533bf c584eade
...@@ -147,6 +147,11 @@ point, the setting of the flag instructs the server not to choose a ...@@ -147,6 +147,11 @@ point, the setting of the flag instructs the server not to choose a
subnet, an action that severely limits further processing; the server subnet, an action that severely limits further processing; the server
will be only able to offer global options - no addresses will be assigned. will be only able to offer global options - no addresses will be assigned.
% DHCP4_INVALID_ADDRESS_INIT_REBOOT invalid address %1 requested by INIT-REBOOT client (id: %2, hwaddr: %3)
This debug message is issued when the client being in the INIT-REBOOT state
requested an address which is not assigned to him. The server will respond
to this client with DHCPNAK.
% DHCP4_LEASE_ADVERT lease %1 advertised (client client-id %2, hwaddr %3) % DHCP4_LEASE_ADVERT lease %1 advertised (client client-id %2, hwaddr %3)
This debug message indicates that the server successfully advertised This debug message indicates that the server successfully advertised
a lease. It is up to the client to choose one server out of othe advertised a lease. It is up to the client to choose one server out of othe advertised
......
...@@ -940,9 +940,23 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) { ...@@ -940,9 +940,23 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
if (opt) { if (opt) {
client_id = ClientIdPtr(new ClientId(opt->getData())); client_id = ClientIdPtr(new ClientId(opt->getData()));
} }
// client-id is not mandatory in DHCPv4 // client-id is not mandatory in DHCPv4
IOAddress hint = question->getYiaddr(); // Get the server identifier. It will be used to determine the state
// of the client.
OptionCustomPtr opt_serverid = boost::dynamic_pointer_cast<
OptionCustom>(question->getOption(DHO_DHCP_SERVER_IDENTIFIER));
// Try to get the Requested IP Address option and use the address as a hint
// for the allocation engine. If the server doesn't already have a lease
// for this client it will try to allocate the one requested.
OptionCustomPtr opt_requested_address = boost::dynamic_pointer_cast<
OptionCustom>(question->getOption(DHO_DHCP_REQUESTED_ADDRESS));
IOAddress hint("0.0.0.0");
if (opt_requested_address) {
hint = opt_requested_address->readAddress();
}
HWAddrPtr hwaddr = question->getHWAddr(); HWAddrPtr hwaddr = question->getHWAddr();
...@@ -954,6 +968,25 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) { ...@@ -954,6 +968,25 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
// allocation. // allocation.
bool fake_allocation = (question->getType() == DHCPDISCOVER); bool fake_allocation = (question->getType() == DHCPDISCOVER);
// If there is no server id and there is a Requested IP Address option
// the client is in the INIT-REBOOT state in which the server has to
// determine whether the client's notion of the address has to be verified.
if (!fake_allocation && !opt_serverid && opt_requested_address) {
Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(hint);
if (!lease) {
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL,
DHCP4_INVALID_ADDRESS_INIT_REBOOT)
.arg(hint.toText())
.arg(client_id ? client_id->toText():"(no client-id)")
.arg(hwaddr ? hwaddr->toText():"(no hwaddr info)");
answer->setType(DHCPNAK);
answer->setYiaddr(IOAddress("0.0.0.0"));
return;
}
}
CalloutHandlePtr callout_handle = getCalloutHandle(question); CalloutHandlePtr callout_handle = getCalloutHandle(question);
std::string hostname; std::string hostname;
...@@ -993,8 +1026,8 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) { ...@@ -993,8 +1026,8 @@ Dhcpv4Srv::assignLease(const Pkt4Ptr& question, Pkt4Ptr& answer) {
/// @todo pass the actual FQDN data. /// @todo pass the actual FQDN data.
Lease4Ptr old_lease; Lease4Ptr old_lease;
Lease4Ptr lease = alloc_engine_->allocateLease4(subnet, client_id, hwaddr, Lease4Ptr lease = alloc_engine_->allocateLease4(subnet, client_id, hwaddr,
hint, fqdn_fwd, fqdn_rev, hint, fqdn_fwd, fqdn_rev,
hostname, hostname,
fake_allocation, fake_allocation,
callout_handle, callout_handle,
old_lease); old_lease);
......
...@@ -90,6 +90,7 @@ dhcp4_unittests_SOURCES += fqdn_unittest.cc ...@@ -90,6 +90,7 @@ dhcp4_unittests_SOURCES += fqdn_unittest.cc
dhcp4_unittests_SOURCES += marker_file.cc dhcp4_unittests_SOURCES += marker_file.cc
dhcp4_unittests_SOURCES += dhcp4_client.cc dhcp4_client.h dhcp4_unittests_SOURCES += dhcp4_client.cc dhcp4_client.h
dhcp4_unittests_SOURCES += inform_unittest.cc dhcp4_unittests_SOURCES += inform_unittest.cc
dhcp4_unittests_SOURCES += dora_unittest.cc
if CONFIG_BACKEND_BUNDY if CONFIG_BACKEND_BUNDY
# For Bundy backend, we only need to run the usual tests. There are no # For Bundy backend, we only need to run the usual tests. There are no
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <boost/pointer_cast.hpp> #include <boost/pointer_cast.hpp>
#include <cstdlib> #include <cstdlib>
using namespace isc::asiolink;
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
namespace test { namespace test {
...@@ -38,9 +40,10 @@ Dhcp4Client::Configuration::reset() { ...@@ -38,9 +40,10 @@ Dhcp4Client::Configuration::reset() {
log_servers_.clear(); log_servers_.clear();
quotes_servers_.clear(); quotes_servers_.clear();
serverid_ = asiolink::IOAddress("0.0.0.0"); serverid_ = asiolink::IOAddress("0.0.0.0");
lease_ = Lease4();
} }
Dhcp4Client::Dhcp4Client() : Dhcp4Client::Dhcp4Client(const Dhcp4Client::State& state) :
config_(), config_(),
curr_transid_(0), curr_transid_(0),
dest_addr_("255.255.255.255"), dest_addr_("255.255.255.255"),
...@@ -49,10 +52,12 @@ Dhcp4Client::Dhcp4Client() : ...@@ -49,10 +52,12 @@ Dhcp4Client::Dhcp4Client() :
requested_options_(), requested_options_(),
server_facing_relay_addr_("10.0.0.2"), server_facing_relay_addr_("10.0.0.2"),
srv_(boost::shared_ptr<NakedDhcpv4Srv>(new NakedDhcpv4Srv(0))), srv_(boost::shared_ptr<NakedDhcpv4Srv>(new NakedDhcpv4Srv(0))),
state_(state),
use_relay_(false) { use_relay_(false) {
} }
Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv) : Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv,
const Dhcp4Client::State& state) :
config_(), config_(),
curr_transid_(0), curr_transid_(0),
dest_addr_("255.255.255.255"), dest_addr_("255.255.255.255"),
...@@ -61,9 +66,19 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv) : ...@@ -61,9 +66,19 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv) :
requested_options_(), requested_options_(),
server_facing_relay_addr_("10.0.0.2"), server_facing_relay_addr_("10.0.0.2"),
srv_(srv), srv_(srv),
state_(state),
use_relay_(false) { use_relay_(false) {
} }
void
Dhcp4Client::addRequestedAddress(const asiolink::IOAddress& addr) {
if (context_.query_) {
Option4AddrLstPtr opt(new Option4AddrLst(DHO_DHCP_REQUESTED_ADDRESS,
addr));
context_.query_->addOption(opt);
}
}
void void
Dhcp4Client::applyConfiguration() { Dhcp4Client::applyConfiguration() {
Pkt4Ptr resp = context_.response_; Pkt4Ptr resp = context_.response_;
...@@ -104,7 +119,12 @@ Dhcp4Client::applyConfiguration() { ...@@ -104,7 +119,12 @@ Dhcp4Client::applyConfiguration() {
config_.serverid_ = opt_serverid->readAddress(); config_.serverid_ = opt_serverid->readAddress();
} }
/// @todo Other possible configuration, e.g. lease. /// @todo Set the valid lifetime, t1, t2 etc.
config_.lease_ = Lease4(IOAddress(context_.response_->getYiaddr()),
&context_.response_->getHWAddr()->hwaddr_[0],
context_.response_->getHWAddr()->hwaddr_.size(),
0, 0, 0, 0, 0, time(NULL), 0, false, false,
"");
} }
void void
...@@ -123,21 +143,33 @@ Dhcp4Client::createMsg(const uint8_t msg_type) { ...@@ -123,21 +143,33 @@ Dhcp4Client::createMsg(const uint8_t msg_type) {
return (msg); return (msg);
} }
void
Dhcp4Client::doDiscover(const boost::shared_ptr<IOAddress>& requested_addr) {
context_.query_ = createMsg(DHCPDISCOVER);
// Request options if any.
includePRL();
if (requested_addr) {
addRequestedAddress(*requested_addr);
}
// Send the message to the server.
sendMsg(context_.query_);
// Expect response.
context_.response_ = receiveOneMsg();
}
void
Dhcp4Client::doDORA(const boost::shared_ptr<IOAddress>& requested_addr) {
doDiscover(requested_addr);
if (context_.response_ && (context_.response_->getType() == DHCPOFFER)) {
doRequest();
}
}
void void
Dhcp4Client::doInform(const bool set_ciaddr) { Dhcp4Client::doInform(const bool set_ciaddr) {
context_.query_ = createMsg(DHCPINFORM); context_.query_ = createMsg(DHCPINFORM);
// Request options if any. // Request options if any.
if (!requested_options_.empty()) { includePRL();
// Include Parameter Request List if at least one option code
// has been specified to be requested.
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
DHO_DHCP_PARAMETER_REQUEST_LIST));
for (std::set<uint8_t>::const_iterator opt = requested_options_.begin();
opt != requested_options_.end(); ++opt) {
prl->addValue(*opt);
}
context_.query_->addOption(prl);
}
// The client sending a DHCPINFORM message has an IP address obtained // The client sending a DHCPINFORM message has an IP address obtained
// by some other means, e.g. static configuration. The lease which we // by some other means, e.g. static configuration. The lease which we
// are using here is most likely set by the createLease method. // are using here is most likely set by the createLease method.
...@@ -159,6 +191,75 @@ Dhcp4Client::doInform(const bool set_ciaddr) { ...@@ -159,6 +191,75 @@ Dhcp4Client::doInform(const bool set_ciaddr) {
} }
} }
void
Dhcp4Client::doRequest() {
context_.query_ = createMsg(DHCPREQUEST);
// Set ciaddr.
if ((state_ == SELECTING) || (state_ == INIT_REBOOT)) {
context_.query_->setCiaddr(IOAddress("0.0.0.0"));
} else {
context_.query_->setCiaddr(IOAddress(config_.lease_.addr_));
}
// Requested IP address.
if (state_ == SELECTING) {
if (context_.response_ &&
(context_.response_->getType() == DHCPOFFER) &&
(context_.response_->getYiaddr() != IOAddress("0.0.0.0"))) {
addRequestedAddress(context_.response_->getYiaddr());
} else {
isc_throw(Dhcp4ClientError, "error sending the DHCPREQUEST because"
" the received DHCPOFFER message was invalid");
}
} else if (state_ == INIT_REBOOT) {
addRequestedAddress(config_.lease_.addr_);
}
// Server identifier.
if (state_ == SELECTING) {
if (context_.response_) {
OptionPtr opt_serverid =
context_.response_->getOption(DHO_DHCP_SERVER_IDENTIFIER);
if (!opt_serverid) {
isc_throw(Dhcp4ClientError, "missing server identifier in the"
" server's response");
}
context_.query_->addOption(opt_serverid);
}
}
// Request options if any.
includePRL();
// Send the message to the server.
sendMsg(context_.query_);
// Expect response.
context_.response_ = receiveOneMsg();
// If the server has responded, store the configuration received.
if (context_.response_) {
applyConfiguration();
}
}
void
Dhcp4Client::includePRL() {
if (!context_.query_) {
isc_throw(Dhcp4ClientError, "pointer to the query must not be NULL"
" when adding option codes to the PRL option");
} else if (!requested_options_.empty()) {
// Include Parameter Request List if at least one option code
// has been specified to be requested.
OptionUint8ArrayPtr prl(new OptionUint8Array(Option::V4,
DHO_DHCP_PARAMETER_REQUEST_LIST));
for (std::set<uint8_t>::const_iterator opt = requested_options_.begin();
opt != requested_options_.end(); ++opt) {
prl->addValue(*opt);
}
context_.query_->addOption(prl);
}
}
HWAddrPtr HWAddrPtr
Dhcp4Client::generateHWAddr(const uint8_t htype) const { Dhcp4Client::generateHWAddr(const uint8_t htype) const {
if (htype != HTYPE_ETHER) { if (htype != HTYPE_ETHER) {
......
...@@ -27,6 +27,13 @@ namespace isc { ...@@ -27,6 +27,13 @@ namespace isc {
namespace dhcp { namespace dhcp {
namespace test { namespace test {
/// @brief General error emitted by the DHCP4 test client.
class Dhcp4ClientError : public isc::Exception {
public:
Dhcp4ClientError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief DHCPv4 client used for unit testing. /// @brief DHCPv4 client used for unit testing.
/// ///
/// This class implements a DHCPv4 "client" which interoperates with the /// This class implements a DHCPv4 "client" which interoperates with the
...@@ -45,6 +52,14 @@ namespace test { ...@@ -45,6 +52,14 @@ namespace test {
class Dhcp4Client : public boost::noncopyable { class Dhcp4Client : public boost::noncopyable {
public: public:
/// @brief States of the DHCP client.
enum State {
SELECTING,
INIT_REBOOT,
RENEWING,
REBINDING
};
/// @brief Holds the DHCPv4 messages taking part in transaction between /// @brief Holds the DHCPv4 messages taking part in transaction between
/// the client and the server. /// the client and the server.
struct Context { struct Context {
...@@ -79,12 +94,16 @@ public: ...@@ -79,12 +94,16 @@ public:
}; };
/// @brief Creates a new client. /// @brief Creates a new client.
Dhcp4Client(); ///
/// @param Initial client's state.
Dhcp4Client(const State& state = SELECTING);
/// @brief Creates a new client that communicates with a specified server. /// @brief Creates a new client that communicates with a specified server.
/// ///
/// @param srv An instance of the DHCPv4 server to be used. /// @param srv An instance of the DHCPv4 server to be used.
Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv); /// @param state Initial client's state.
Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv>& srv,
const State& state = SELECTING);
/// @brief Creates a lease for the client using the specified address /// @brief Creates a lease for the client using the specified address
/// and valid lifetime. /// and valid lifetime.
...@@ -101,6 +120,31 @@ public: ...@@ -101,6 +120,31 @@ public:
/// @param valid_lft Valid lifetime. /// @param valid_lft Valid lifetime.
void createLease(const asiolink::IOAddress& addr, const uint32_t valid_lft); void createLease(const asiolink::IOAddress& addr, const uint32_t valid_lft);
/// @brief Sends DHCPDISCOVER message to the server and receives response.
///
/// The message being sent to the server includes Parameter Request List
/// option if any options to be requested have been specified using the
/// @c requestOptions or @c requestOption methods.
///
/// The configuration returned by the server in the DHCPOFFER message is
/// NOT stored in the client configuration: @c config_.
///
/// @param requested_addr A pointer to the IP Address to be sent in the
/// Requested IP Address option or NULL if the option should not be
/// included.
void doDiscover(const boost::shared_ptr<asiolink::IOAddress>&
requested_addr = boost::shared_ptr<asiolink::IOAddress>());
/// @brief Perform 4-way exchange with a server.
///
/// This method calls @c doDiscover and @c doRequest to perform the 4-way
/// exchange with the server.
///
/// @param requested_addr A pointer to the address to be requested using the
/// Requested IP Address option.
void doDORA(const boost::shared_ptr<asiolink::IOAddress>&
requested_addr = boost::shared_ptr<asiolink::IOAddress>());
/// @brief Sends DHCPINFORM message to the server and receives response. /// @brief Sends DHCPINFORM message to the server and receives response.
/// ///
/// This function simulates sending the DHCPINFORM message to the server /// This function simulates sending the DHCPINFORM message to the server
...@@ -121,6 +165,32 @@ public: ...@@ -121,6 +165,32 @@ public:
/// an error occurs. /// an error occurs.
void doInform(const bool set_ciaddr = true); void doInform(const bool set_ciaddr = true);
/// @brief Sends DHCPREQUEST Message to the server and receives a response.
///
/// This method simulates sending the DHCPREQUEST message to the server and
/// receiving a response. The DHCPREQUEST message can be used by the client
/// being in various states:
/// - SELECTING - client is trying to obtain a new lease and it has selected
/// the server using the DHCPDISCOVER.
/// - INIT-REBOOT - client cached an address it was previously using and is
/// now trying to verify if this address is still valid.
/// - RENEW - client's renewal timer has passed and the client is trying to
/// extend the lifetime of the lease.
/// - REBIND - client's rebind timer has passed and the client is trying to
/// extend the lifetime of the lease from any server.
///
/// Depending on the state that the client is in, different combinations of
/// - ciaddr
/// - Requested IP Address option
/// - server identifier
/// are used (as per RFC2131, section 4.3.2). Therefore, the unit tests
/// must setthe appropriate state of the client prior to calling this
/// method using the @c setState function.
///
/// When the server returns the DHCPACK the configuration carried in the
/// DHCPACK message is applied and can be obtained from the @c config_.
void doRequest();
/// @brief Generates a hardware address used by the client. /// @brief Generates a hardware address used by the client.
/// ///
/// It assigns random values to the bytes of the hardware address. /// It assigns random values to the bytes of the hardware address.
...@@ -195,6 +265,16 @@ public: ...@@ -195,6 +265,16 @@ public:
dest_addr_ = dest_addr; dest_addr_ = dest_addr;
} }
/// @brief Sets client state.
///
/// Depending on the current state the client's behavior is different
/// when sending Request messages as per RFC2131, section 4.3.2.
///
/// @param state New client's state.
void setState(const State& state) {
state_ = state;
}
/// @brief Simulate sending messages through a relay. /// @brief Simulate sending messages through a relay.
/// ///
/// @param use Parameter which 'true' value indicates that client should /// @param use Parameter which 'true' value indicates that client should
...@@ -216,6 +296,12 @@ public: ...@@ -216,6 +296,12 @@ public:
private: private:
/// @brief Creates and adds Requested IP Address option to the client's
/// query.
///
/// @param addr Address to be added in the Requested IP Address option.
void addRequestedAddress(const asiolink::IOAddress& addr);
/// @brief Stores configuration received from the server. /// @brief Stores configuration received from the server.
/// ///
/// This methods stores the configuration obtained from the DHCP server /// This methods stores the configuration obtained from the DHCP server
...@@ -236,6 +322,14 @@ private: ...@@ -236,6 +322,14 @@ private:
/// @return An instance of the message created. /// @return An instance of the message created.
Pkt4Ptr createMsg(const uint8_t msg_type); Pkt4Ptr createMsg(const uint8_t msg_type);
/// @brief Include PRL Option in the query message.
///
/// This function creates the instance of the PRL (Parameter Request List)
/// option and adds option codes from the @c requested_options_ to it.
/// It later adds the PRL option to the @c context_.query_ message
/// if it is non-NULL.
void includePRL();
/// @brief Simulates reception of the message from the server. /// @brief Simulates reception of the message from the server.
/// ///
/// @return Received message. /// @return Received message.
...@@ -274,6 +368,9 @@ private: ...@@ -274,6 +368,9 @@ private:
/// @brief Pointer to the server that the client is communicating with. /// @brief Pointer to the server that the client is communicating with.
boost::shared_ptr<NakedDhcpv4Srv> srv_; boost::shared_ptr<NakedDhcpv4Srv> srv_;
/// @brief Current state of the client.
State state_;
/// @brief Enable relaying messages to the server. /// @brief Enable relaying messages to the server.
bool use_relay_; bool use_relay_;
}; };
......
...@@ -590,92 +590,6 @@ TEST_F(Dhcpv4SrvTest, DiscoverNoTimers) { ...@@ -590,92 +590,6 @@ TEST_F(Dhcpv4SrvTest, DiscoverNoTimers) {
checkClientId(offer, clientid); checkClientId(offer, clientid);
} }
// This test verifies that incoming DISCOVER can be handled properly, that an
// OFFER is generated, that the response has an address and that address
// really belongs to the configured pool.
//
// constructed very simple DISCOVER message with:
// - client-id option
// - address set to specific value as hint
//
// expected returned OFFER message:
// - copy of client-id
// - server-id
// - offered address
TEST_F(Dhcpv4SrvTest, DiscoverHint) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("192.0.2.107");
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
OptionPtr clientid = generateClientId();
dis->addOption(clientid);
dis->setYiaddr(hint);
dis->setIface("eth1");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// Check if we get response at all
checkResponse(offer, DHCPOFFER, 1234);
// Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly
checkAddressParams(offer, subnet_, true, true);
EXPECT_EQ(offer->getYiaddr(), hint);
// Check identifiers
checkServerId(offer, srv->getServerID());
checkClientId(offer, clientid);
}
// This test verifies that incoming DISCOVER can be handled properly, that an
// OFFER is generated, that the response has an address and that address
// really belongs to the configured pool.
//
// constructed very simple DISCOVER message with:
// - address set to specific value as hint
//
// expected returned OFFER message:
// - copy of client-id
// - server-id
// - offered address
TEST_F(Dhcpv4SrvTest, DiscoverNoClientId) {
IfaceMgrTestConfig test_config(true);
IfaceMgr::instance().openSockets4();
boost::scoped_ptr<NakedDhcpv4Srv> srv;
ASSERT_NO_THROW(srv.reset(new NakedDhcpv4Srv(0)));
IOAddress hint("192.0.2.107");
Pkt4Ptr dis = Pkt4Ptr(new Pkt4(DHCPDISCOVER, 1234));
dis->setRemoteAddr(IOAddress("192.0.2.1"));
dis->setYiaddr(hint);
dis->setHWAddr(generateHWAddr(6));
dis->setIface("eth1");
// Pass it to the server and get an offer
Pkt4Ptr offer = srv->processDiscover(dis);
// Check if we get response at all
checkResponse(offer, DHCPOFFER, 1234);
// Check that address was returned from proper range, that its lease
// lifetime is correct, that T1 and T2 are returned properly
checkAddressParams(offer, subnet_, true, true);
EXPECT_EQ(offer->getYiaddr(), hint);
// Check identifiers
checkServerId(offer, srv->getServerID());
}
// This test verifies that incoming DISCOVER can be handled properly, that an // This test verifies that incoming DISCOVER can be handled properly, that an
// OFFER is generated, that the response has an address and that address // OFFER is generated, that the response has an address and that address
// really belongs to the configured pool. // really belongs to the configured pool.
...@@ -825,58 +739,6 @@ TEST_F(Dhcpv4SrvTest, discoverEchoClientId) { ...@@ -825,58 +739,6 @@ TEST_F(Dhcpv4SrvTest, discoverEchoClientId) {
checkClientId(offer, clientid); checkClientId(offer, clientid);
} }