Commit 36494139 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3232'

parents 51b46695 8ae73d0c
......@@ -5868,8 +5868,8 @@ Dhcp6/renew-timer 1000 integer (default)
<simpara>Prefix delegation is not supported.</simpara>
</listitem>
<listitem>
<simpara>Rebinding (REBIND), confirmation (CONFIRM),
and duplication report (DECLINE) are not yet supported.</simpara>
<simpara>Confirmation (CONFIRM), and duplication report (DECLINE)
are not yet supported.</simpara>
</listitem>
<listitem>
<simpara>DNS Update is not supported.</simpara>
......
......@@ -120,6 +120,55 @@ A "libreload" command was issued to reload the hooks libraries but for
some reason the reload failed. Other error messages issued from the
hooks framework will indicate the nature of the problem.
% DHCP6_EXTEND_LEASE_SUBNET_SELECTED the %1 subnet was selected for client extending its lease
This is a debug message informing that a given subnet was selected. It will
be used for extending lifetime of the lease. This is one of the early steps
in the processing of incoming client message.
% DHCP6_EXTEND_LEASE_SUBNET_SELECT_FAILED failed to select a subnet for received %1: src=%2 type=%3
This warning message is output when a Renew or Rebind was received from a
subnet for which the DHCPv6 server has not been configured. The cause is
most likely due to a misconfiguration of the server. The packet processing
will continue, but the response will only contain generic configuration
parameters and no addresses or prefixes.
% DHCP6_EXTEND_NA_UNKNOWN received unknown IA_NA from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to extend the lease
for the address (in the IA_NA option) but no such lease is known by the server.
It typically means that client has attempted to use its lease past its
lifetime: causes of this include a adjustment of the client's date/time
setting or poor support on the client for sleep/recovery. A properly
implemented client will recover from such a situation by restarting the
lease allocation process after receiving a negative reply from the server.
An alternative cause could be that the server has lost its database
recently and does not recognize its well-behaving clients. This is more
probable if you see many such messages. Clients will recover from this,
but they will most likely get a different IP addresses and experience
a brief service interruption.
% DHCP6_EXTEND_NA_UNKNOWN_SUBNET %1 message received from client on unknown subnet (duid=%2, iaid=%3)
A warning message indicating that a client is attempting to extend lease lifetime
for the address, but the server does not have any information about the subnet this
client belongs to. This may mean that faulty the mobile client changed its location
and is trying to renew its old address (client is supposed to send confirm, not rewew
in such cases, according to RFC3315) or the server configuration has changed and
information about existing subnet was removed. Note that in a sense this is worse
case of DHCP6_EXTEND_NA_UNKNOWN, as not only the lease is unknown, but also the subnet
is. Depending on the reasons of this condition, it may or may not correct on its own.
% DHCP6_EXTEND_PD_NO_BINDING client sent a %1 message to extend lifetimes of prefixes for an unknown binding: duid=%2, iaid=%3, subnet=%4
This warning message is logged when a client attempts to extend the lifetime of the
prefix it is using, but the server was unable to find the binding to which
this lease belongs. This error condition has different implications for the
Renew and Rebind messages. For the former, the server will respond with NoBinding
status code. For the latter, the server will discard the message.
% DHCP6_EXTEND_PD_UNKNOWN_SUBNET %1 message received from client on unknown subnet (duid=%2, iaid=%3)
A warning message indicating that a client is attempting to extend lease lifetime
for the prefix, but the server doesn't have any information about the subnet this
client belongs to.
% DHCP6_HOOK_BUFFER_RCVD_SKIP received DHCPv6 buffer was dropped because a callout set the skip flag
This debug message is printed when a callout installed on buffer6_receive
hook point set the skip flag. For this particular hook point, the
......@@ -132,6 +181,12 @@ setting of the flag by a callout instructs the server to drop the packet.
Server completed all the processing (e.g. may have assigned, updated
or released leases), but the response will not be send to the client.
% DHCP6_HOOK_LEASE6_EXTEND_SKIP DHCPv6 lease lifetime was not extended because a callout set the skip flag for message %1
or lease6_rebind hook point set the skip flag. For this particular hook
point, the setting of the flag by a callout instructs the server to not
extend the lifetime for a lease. If client requested renewal of multiples
leases (by sending multiple IA options), the server will skip the renewal
of the one in question and will proceed with other renewals as usual.
% DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP 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
......@@ -401,16 +456,6 @@ that does belong to it, but the address was expected to be in a different
IA (identity association) container. This probably means that the client's
support for multiple prefixes is flawed.
% DHCP6_RENEW_UNKNOWN_SUBNET RENEW message received from client on unknown subnet (duid=%1, iaid=%2)
A warning message indicating that a client is attempting to renew his lease,
but the server does not have any information about the subnet this client belongs
to. This may mean that faulty the mobile client changed its location and is trying to
renew its old address (client is supposed to send confirm, not rewew in such cases,
according to RFC3315) or the server configuration has changed and information about
existing subnet was removed. Note that in a sense this is worse case of DHCP6_UNKNOWN_RENEW,
as not only the lease is unknown, but also the subnet is. Depending on the reasons
of this condition, it may or may not correct on its own.
% DHCP6_REQUIRED_OPTIONS_CHECK_FAIL %1 message received from %2 failed the following check: %3
This message indicates that received DHCPv6 packet is invalid. This may be due
to a number of reasons, e.g. the mandatory client-id option is missing,
......@@ -519,33 +564,3 @@ This warning message is printed when client attempts to release an prefix
lease, but no such lease is known by the server. See the explanation
of the status code DHCP6_UNKNOWN_RENEW_PD for possible reasons for
such behavior.
% DHCP6_UNKNOWN_RENEW_NA received unknown IA_NA RENEW from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to renew an address
lease (in the IA_NA option) but no such lease is known by the server. It
typically means that client has attempted to use its lease past its
lifetime: causes of this include a adjustment of the client's date/time
setting or poor support on the client for sleep/recovery. A properly
implemented client will recover from such a situation by restarting the
lease allocation process after receiving a negative reply from the server.
An alternative cause could be that the server has lost its database
recently and does not recognize its well-behaving clients. This is more
probable if you see many such messages. Clients will recover from this,
but they will most likely get a different IP addresses and experience
a brief service interruption.
% DHCP6_UNKNOWN_RENEW_PD received unknown IA_NA RENEW from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to renew an address lease
(in IA_NA option), but no such lease is known by the server. It typically means
that client has attempted to use its lease past its lifetime: causes of this
include a adjustment of the clients date/time setting or poor support
for sleep/recovery. A properly implemented client will recover from such
a situation by restarting the lease allocation process after receiving
a negative reply from the server.
An alternative cause could be that the server has lost its database
recently and does not recognize its well-behaving clients. This is more
probable if you see many such messages. Clients will recover from this,
but they will most likely get a different IP addresses and experience
a brief service interruption.
This diff is collapsed.
......@@ -36,6 +36,14 @@
namespace isc {
namespace dhcp {
/// @brief This exception is thrown when DHCP server hits the error which should
/// result in discarding the message being processed.
class DHCPv6DiscardMessageError : public Exception {
public:
DHCPv6DiscardMessageError(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief DHCPv6 server service.
///
/// This class represents DHCPv6 server. It contains all
......@@ -155,6 +163,18 @@ protected:
/// used by the server; false otherwise.
bool testServerID(const Pkt6Ptr& pkt);
/// @brief Check if the message can be sent to unicast.
///
/// This function checks if the received message conforms to the section 15
/// of RFC3315 which says that: "A server MUST discard any Solicit, Confirm,
/// Rebind or Information-request messages it receives with a unicast
/// destination address.
///
/// @param pkt DHCPv6 message to be checked.
/// @return false if the message has been sent to unicast address but it is
/// not allowed according to RFC3315, section 15; true otherwise.
bool testUnicast(const Pkt6Ptr& pkt) const;
/// @brief verifies if specified packet meets RFC requirements
///
/// Checks if mandatory option is really there, that forbidden option
......@@ -279,37 +299,59 @@ protected:
const Pkt6Ptr& query,
boost::shared_ptr<Option6IA> ia);
/// @brief Renews specific IA_NA option
/// @brief Extends lifetime of the specific IA_NA option.
///
/// Generates response to IA_NA in Renew. This typically includes finding a
/// lease that corresponds to the received address. If no such lease is
/// found, an IA_NA response is generated with an appropriate status code.
/// Generates response to IA_NA in Renew or Rebind. This typically includes
/// finding a lease that corresponds to the received address. If no such
/// lease is found, an IA_NA response is generated with an appropriate
/// status code.
///
/// @todo The behavior of this function will need to be extended to support
/// draft-ietf-dhc-dhcpv6-stateful-issues. This draft modifies the behavior
/// described in RFC3315 with respect to Renew and Rebind processing. Key
/// changes are (version -05):
/// - Renewing and Rebinding client MAY request additional bindings by
/// putting an IA for all bindings it desires but has been unable to obtain.
/// Server MAY allocate addresses if it finds that they are appropriate for
/// the link that client is attached to.
/// - When receiving Rebind, if the server determines that the addresses are
/// not appropriate for the link the client is attached to, the server MAY
/// send the IA with address lifetimes set to 0 or discard the message.
///
/// @param subnet subnet the sender belongs to
/// @param duid client's duid
/// @param query client's message
/// @param query client's message (Renew or Rebind)
/// @param answer server's response to the client's message. This
/// message should contain Client FQDN option being sent by the server
/// to the client (if the client sent this option to the server).
/// @param ia IA_NA option that is being renewed
/// @param ia IA_NA option which carries adress for which lease lifetime
/// will be extended.
/// @return IA_NA option (server's response)
OptionPtr renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, const Pkt6Ptr& answer,
boost::shared_ptr<Option6IA> ia);
OptionPtr extendIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, const Pkt6Ptr& answer,
Option6IAPtr ia);
/// @brief Renews specific IA_PD option
/// @brief Extends lifetime of the prefix.
///
/// Generates response to IA_PD in Renew. This typically includes finding a
/// lease that corresponds to the received prefix. If no such lease is
/// found, an IA_PD response is generated with an appropriate status code.
/// This function is called by the logic which processes Renew and Rebind
/// messages to extend the lifetime of the existing prefix.
///
/// The behavior of this function is different in that when there is no
/// binding found in the lease database for the particular client the
/// NoBinding status code is returned when processing Renew, the exception
/// is thrown when there is no binding and the Rebind message is processed
/// (see RFC3633, section 12.2. for details).
///
/// @param subnet subnet the sender belongs to
/// @param duid client's duid
/// @param query client's message
/// @param ia IA_PD option that is being renewed
/// @return IA_PD option (server's response)
OptionPtr renewIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia);
/// @throw DHCPv6DiscardMessageError when the message being processed should
/// be discarded by the server, i.e. there is no binding for the client doing
/// Rebind.
OptionPtr extendIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, Option6IAPtr ia);
/// @brief Releases specific IA_NA option
///
......@@ -455,15 +497,17 @@ protected:
/// records will be performed.
void createRemovalNameChangeRequest(const Lease6Ptr& lease);
/// @brief Attempts to renew received addresses
/// @brief Attempts to extend the lifetime of IAs.
///
/// This function is called when a client sends Renew or Rebind message.
/// It iterates through received IA options and attempts to extend
/// corresponding lease lifetimes. Internally, it calls
/// @c Dhcpv6Srv::extendIA_NA and @c Dhcpv6Srv::extendIA_PD to extend
/// the lifetime of IA_NA and IA_PD leases accordingly.
///
/// It iterates through received IA_NA options and attempts to renew
/// received addresses. If no such leases are found, proper status
/// code is added to reply message. Renewed addresses are added
/// as IA_NA/IAADDR to reply packet.
/// @param renew client's message asking for renew
/// @param query client's Renew or Rebind message
/// @param reply server's response
void renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply);
void extendLeases(const Pkt6Ptr& query, Pkt6Ptr& reply);
/// @brief Attempts to release received addresses
///
......@@ -624,15 +668,15 @@ private:
/// Server DUID (to be sent in server-identifier option)
OptionPtr serverid_;
/// Indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
volatile bool shutdown_;
/// UDP port number on which server listens.
uint16_t port_;
protected:
/// Indicates if shutdown is in progress. Setting it to true will
/// initiate server shutdown procedure.
volatile bool shutdown_;
/// Holds a list of @c isc::dhcp_ddns::NameChangeRequest objects, which
/// are waiting for sending to b10-dhcp-ddns module.
std::queue<isc::dhcp_ddns::NameChangeRequest> name_change_reqs_;
......
......@@ -84,6 +84,8 @@ dhcp6_unittests_SOURCES += ../dhcp6_log.h ../dhcp6_log.cc
dhcp6_unittests_SOURCES += ../ctrl_dhcp6_srv.cc
dhcp6_unittests_SOURCES += ../config_parser.cc ../config_parser.h
dhcp6_unittests_SOURCES += wireshark.cc
dhcp6_unittests_SOURCES += dhcp6_client.cc dhcp6_client.h
dhcp6_unittests_SOURCES += rebind_unittest.cc
nodist_dhcp6_unittests_SOURCES = ../dhcp6_messages.h ../dhcp6_messages.cc
nodist_dhcp6_unittests_SOURCES += marker_file.h test_libraries.h
......@@ -91,6 +93,7 @@ nodist_dhcp6_unittests_SOURCES += marker_file.h test_libraries.h
dhcp6_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
dhcp6_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
dhcp6_unittests_LDADD = $(GTEST_LDADD)
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/dhcp/tests/libdhcptest.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
dhcp6_unittests_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
......
// Copyright (C) 2014 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcp/dhcp6.h>
#include <dhcp/option_custom.h>
#include <dhcp/option6_ia.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/pkt6.h>
#include <dhcpsrv/lease.h>
#include <dhcp6/tests/dhcp6_client.h>
#include <util/buffer.h>
#include <boost/pointer_cast.hpp>
#include <cstdlib>
#include <time.h>
using namespace isc::test;
namespace isc {
namespace dhcp {
namespace test {
Dhcp6Client::Dhcp6Client() :
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_(boost::shared_ptr<NakedDhcpv6Srv>(new NakedDhcpv6Srv(0))),
use_na_(false),
use_pd_(false),
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::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 (!ia) {
continue;
}
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
}
applyLease(lease_info);
}
}
}
void
Dhcp6Client::applyLease(const LeaseInfo& lease_info) {
// Go over existing leases and try to match the one that we have.
for (int i = 0; i < config_.leases_.size(); ++i) {
Lease6 existing_lease = config_.leases_[i].lease_;
// If IAID is matching and there is an actual address assigned
// replace the current lease. The default address is :: if the
// 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;
} else if (lease_info.lease_.addr_ == asiolink::IOAddress("::")) {
config_.leases_[i].status_code_ = lease_info.status_code_;
return;
}
}
// It is a new lease. Add it.
config_.leases_.push_back(lease_info);
}
void
Dhcp6Client::copyIAs(const Pkt6Ptr& source, const Pkt6Ptr& dest) {
typedef OptionCollection Opts;
// Copy IA_NAs.
Opts opts = source->getOptions(D6O_IA_NA);
for (Opts::const_iterator opt = opts.begin(); opt != opts.end(); ++opt) {
dest->addOption(opt->second);
}
// Copy IA_PDs.
opts = source->getOptions(D6O_IA_PD);
for (Opts::const_iterator opt = opts.begin(); opt != opts.end(); ++opt) {
dest->addOption(opt->second);
}
}
void
Dhcp6Client::copyIAsFromLeases(const Pkt6Ptr& dest) const {
// Go over leases and create IA_NA and IA_PD options from them.
// Create one IA per lease.
for (std::vector<LeaseInfo>::const_iterator info = config_.leases_.begin();
info != config_.leases_.end(); ++info) {
Lease6 lease = info->lease_;
if (lease.type_ == Lease::TYPE_NA) {
Option6IAPtr opt(new Option6IA(D6O_IA_NA, lease.iaid_));
opt->setT1(lease.t1_);
opt->setT2(lease.t1_);
opt->addOption(Option6IAAddrPtr(new
Option6IAAddr(D6O_IAADDR,
lease.addr_,
lease.preferred_lft_,
lease.valid_lft_)));
dest->addOption(opt);
} else if (lease.type_ == Lease::TYPE_PD) {
Option6IAPtr opt(new Option6IA(D6O_IA_PD, lease.iaid_));
opt->setT1(lease.t1_);
opt->setT2(lease.t1_);
opt->addOption(Option6IAPrefixPtr(new Option6IAPrefix(D6O_IAPREFIX,
lease.addr_,
lease.prefixlen_,
lease.preferred_lft_,
lease.valid_lft_)));
dest->addOption(opt);
}
}
}
Pkt6Ptr
Dhcp6Client::createMsg(const uint8_t msg_type) {
Pkt6Ptr msg(new Pkt6(msg_type, curr_transid_++));
msg->addOption(getClientId());
return (msg);
}
void
Dhcp6Client::doSARR() {
doSolicit();
// Don't send the Request if there was no Advertise.
if (context_.response_) {
doRequest();
}
}
void
Dhcp6Client::doSolicit() {
context_.query_ = createMsg(DHCPV6_SOLICIT);
if (use_na_) {
context_.query_->addOption(Option6IAPtr(new Option6IA(D6O_IA_NA,
1234)));
}
if (use_pd_) {
context_.query_->addOption(Option6IAPtr(new Option6IA(D6O_IA_PD,
5678)));
}
sendMsg(context_.query_);
context_.response_ = receiveOneMsg();
/// @todo Sanity check here
}
void
Dhcp6Client::doRequest() {
Pkt6Ptr query = createMsg(DHCPV6_REQUEST);
query->addOption(context_.response_->getOption(D6O_SERVERID));
copyIAs(context_.response_, query);
context_.query_ = query;
sendMsg(context_.query_);
context_.response_ = receiveOneMsg();
/// @todo sanity check here.
// Apply new configuration only if the server has responded.
if (context_.response_) {
applyRcvdConfiguration(context_.response_);
}
}
void
Dhcp6Client::doRebind() {
Pkt6Ptr query = createMsg(DHCPV6_REBIND);
copyIAsFromLeases(query);
context_.query_ = query;
sendMsg(context_.query_);
context_.response_ = receiveOneMsg();
// Apply configuration only if the server has responded.
if (context_.response_) {
applyRcvdConfiguration(context_.response_);
}
}
void
Dhcp6Client::fastFwdTime(const uint32_t secs) {
// Iterate over all leases and move their cltt backwards.
for (int i = 0; i < config_.leases_.size(); ++i) {
config_.leases_[i].lease_.cltt_ -= secs;
}
}
DuidPtr
Dhcp6Client::generateDUID(DUID::DUIDType duid_type) const {
std::vector<uint8_t> duid;
/// @todo remove this check once other DUID types are implemented.
if (duid_type != DUID::DUID_LLT) {
isc_throw(NotImplemented, "currently the Dhcp6Client only supports"
" generation of DUID LLT");
}
duid.push_back(static_cast<uint8_t>(duid_type));
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));
}
return (DuidPtr(new DUID(duid)));
}
OptionPtr
Dhcp6Client::getClientId() const {
OptionPtr opt_client_id(new Option(Option::V6,
D6O_CLIENTID,
duid_->getDuid().begin(),
duid_->getDuid().end()));
return (opt_client_id);
}
void
Dhcp6Client::modifyDUID() {