Commit 1d77f223 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[4320] ClientContext6 now holds information about multiple IAs.

parent 522f9824
......@@ -276,12 +276,16 @@ Dhcpv6Srv::testUnicast(const Pkt6Ptr& pkt) const {
return (true);
}
AllocEngine::ClientContext6
Dhcpv6Srv::createContext(const Pkt6Ptr& pkt) {
AllocEngine::ClientContext6 ctx;
void
Dhcpv6Srv::initContext(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx) {
ctx.subnet_ = selectSubnet(pkt);
ctx.duid_ = pkt->getClientId(),
ctx.fwd_dns_update_ = false;
ctx.rev_dns_update_ = false;
ctx.fake_allocation_ = false;
ctx.hostname_ = "";
ctx.query_ = pkt;
ctx.duid_ = pkt->getClientId();
ctx.callout_handle_ = getCalloutHandle(pkt);
ctx.hwaddr_ = getMAC(pkt);
// Collect host identifiers if host reservations enabled. The identifiers
......@@ -314,8 +318,6 @@ Dhcpv6Srv::createContext(const Pkt6Ptr& pkt) {
// Find host reservations using specified identifiers.
alloc_engine_->findReservation(ctx);
}
return (ctx);
}
bool Dhcpv6Srv::run() {
......@@ -1283,7 +1285,7 @@ Dhcpv6Srv::getMAC(const Pkt6Ptr& pkt) {
OptionPtr
Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
boost::shared_ptr<Option6IA> ia) {
// Check if the client sent us a hint in his IA_NA. Clients may send an
......@@ -1302,8 +1304,7 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
.arg(hint_opt ? hint.toText() : "(no hint)");
// convenience values
const Subnet6Ptr& subnet = orig_ctx.subnet_;
const DuidPtr& duid = orig_ctx.duid_;
const Subnet6Ptr& subnet = ctx.subnet_;
// If there is no subnet selected for handling this IA_NA, the only thing left to do is
// to say that we are sorry, but the user won't get an address. As a convenience, we
......@@ -1351,14 +1352,13 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// will try to honor the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well.
AllocEngine::ClientContext6 ctx(subnet, duid, ia->getIAID(),
hint, Lease::TYPE_NA, do_fwd, do_rev,
orig_ctx.hostname_, fake_allocation);
ctx.callout_handle_ = getCalloutHandle(query);
ctx.hwaddr_ = orig_ctx.hwaddr_;
ctx.host_ = orig_ctx.host_;
ctx.query_ = orig_ctx.query_;
ctx.host_identifiers_ = orig_ctx.host_identifiers_;
ctx.createIAContext();
ctx.fwd_dns_update_ = do_fwd;
ctx.rev_dns_update_ = do_rev;
ctx.fake_allocation_ = fake_allocation;
ctx.currentIA().iaid_ = ia->getIAID();
ctx.currentIA().addHint(hint);
ctx.currentIA().type_ = Lease::TYPE_NA;
Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
......@@ -1417,7 +1417,7 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
OptionPtr
Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
boost::shared_ptr<Option6IA> ia) {
// Check if the client sent us a hint in his IA_PD. Clients may send an
......@@ -1437,8 +1437,7 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
.arg(hint_opt ? hint.toText() : "(no hint)");
const Subnet6Ptr& subnet = orig_ctx.subnet_;
const DuidPtr& duid = orig_ctx.duid_;
const Subnet6Ptr& subnet = ctx.subnet_;
// Create IA_PD that we will put in the response.
// Do not use OptionDefinition to create option's instance so
......@@ -1474,13 +1473,13 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// will try to honor the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well.
AllocEngine::ClientContext6 ctx(subnet, duid, ia->getIAID(), hint, Lease::TYPE_PD,
false, false, string(), fake_allocation);
ctx.callout_handle_ = getCalloutHandle(query);
ctx.hwaddr_ = orig_ctx.hwaddr_;
ctx.host_ = orig_ctx.host_;
ctx.query_ = orig_ctx.query_;
ctx.host_identifiers_ = orig_ctx.host_identifiers_;
ctx.createIAContext();
ctx.fake_allocation_ = fake_allocation;
ctx.currentIA().iaid_ = ia->getIAID();
ctx.currentIA().addHint(hint);
ctx.currentIA().type_ = Lease::TYPE_PD;
Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
......@@ -1532,7 +1531,7 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
OptionPtr
Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
boost::shared_ptr<Option6IA> ia) {
LOG_DEBUG(lease6_logger, DBG_DHCP6_DETAIL, DHCP6_PROCESS_IA_NA_EXTEND)
......@@ -1540,8 +1539,7 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
.arg(ia->getIAID());
// convenience values
const Subnet6Ptr& subnet = orig_ctx.subnet_;
const DuidPtr& duid = orig_ctx.duid_;
const Subnet6Ptr& subnet = ctx.subnet_;
// Create empty IA_NA option with IAID matching the request.
Option6IAPtr ia_rsp(new Option6IA(D6O_IA_NA, ia->getIAID()));
......@@ -1575,16 +1573,12 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
do_fwd, do_rev);
}
// Create client context for this renewal
AllocEngine::ClientContext6 ctx(subnet, duid, ia->getIAID(),
IOAddress::IPV6_ZERO_ADDRESS(), Lease::TYPE_NA,
do_fwd, do_rev, orig_ctx.hostname_, false);
ctx.callout_handle_ = getCalloutHandle(query);
ctx.query_ = query;
ctx.ia_rsp_ = ia_rsp;
ctx.hwaddr_ = orig_ctx.hwaddr_;
ctx.host_ = orig_ctx.host_;
ctx.createIAContext();
ctx.fwd_dns_update_ = do_fwd;
ctx.rev_dns_update_ = do_rev;
ctx.currentIA().iaid_ = ia->getIAID();
ctx.currentIA().type_ = Lease::TYPE_NA;
ctx.currentIA().ia_rsp_ = ia_rsp;
// Extract the addresses that the client is trying to obtain.
OptionCollection addrs = ia->getOptions();
......@@ -1603,7 +1597,7 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// this.
continue;
}
ctx.hints_.push_back(make_pair(iaaddr->getAddress(), 128));
ctx.currentIA().addHint(iaaddr->getAddress());
}
Lease6Collection leases = alloc_engine_->renewLeases6(ctx);
......@@ -1613,6 +1607,8 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// - what we actually assigned in leases
// - old leases that are no longer valid in ctx.old_leases_
AllocEngine::HintContainer hints = ctx.currentIA().hints_;
// For all leases we have now, add the IAADDR with non-zero lifetimes.
for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
Option6IAAddrPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
......@@ -1624,22 +1620,21 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
.arg(ia_rsp->getIAID());
// Now remove this address from the hints list.
AllocEngine::HintType tmp((*l)->addr_, 128);
ctx.hints_.erase(std::remove(ctx.hints_.begin(), ctx.hints_.end(), tmp),
ctx.hints_.end());
AllocEngine::HintType hint_type((*l)->addr_, 128);
hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
hints.end());
}
// For the leases that we just retired, send the addresses with 0 lifetimes.
for (Lease6Collection::const_iterator l = ctx.old_leases_.begin();
l != ctx.old_leases_.end(); ++l) {
for (Lease6Collection::const_iterator l = ctx.currentIA().old_leases_.begin();
l != ctx.currentIA().old_leases_.end(); ++l) {
Option6IAAddrPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
(*l)->addr_, 0, 0));
ia_rsp->addOption(iaaddr);
// Now remove this address from the hints list.
AllocEngine::HintType tmp((*l)->addr_, 128);
ctx.hints_.erase(std::remove(ctx.hints_.begin(), ctx.hints_.end(), tmp),
ctx.hints_.end());
AllocEngine::HintType hint_type((*l)->addr_, 128);
hints.erase(std::remove(hints.begin(), hints.end(), hint_type), hints.end());
// If the new FQDN settings have changed for the lease, we need to
// delete any existing FQDN records for this lease.
......@@ -1659,8 +1654,8 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
// Finally, if there are any addresses requested that we haven't dealt with
// already, inform the client that he can't have them.
for (AllocEngine::HintContainer::const_iterator hint = ctx.hints_.begin();
hint != ctx.hints_.end(); ++hint) {
for (AllocEngine::HintContainer::const_iterator hint = hints.begin();
hint != hints.end(); ++hint) {
Option6IAAddrPtr iaaddr(new Option6IAAddr(D6O_IAADDR,
hint->first, 0, 0));
ia_rsp->addOption(iaaddr);
......@@ -1682,15 +1677,15 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
OptionPtr
Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
boost::shared_ptr<Option6IA> ia) {
LOG_DEBUG(lease6_logger, DBG_DHCP6_DETAIL, DHCP6_PROCESS_IA_PD_EXTEND)
.arg(query->getLabel())
.arg(ia->getIAID());
const Subnet6Ptr& subnet = orig_ctx.subnet_;
const DuidPtr& duid = orig_ctx.duid_;
const Subnet6Ptr& subnet = ctx.subnet_;
const DuidPtr& duid = ctx.duid_;
// Let's create a IA_PD response and fill it in later
Option6IAPtr ia_rsp(new Option6IA(D6O_IA_PD, ia->getIAID()));
......@@ -1729,16 +1724,10 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
ia_rsp->setT1(subnet->getT1());
ia_rsp->setT2(subnet->getT2());
// Create client context for this renewal
static const IOAddress none("::");
AllocEngine::ClientContext6 ctx(subnet, duid, ia->getIAID(), none,
Lease::TYPE_PD, false, false, string(""),
false);
ctx.callout_handle_ = getCalloutHandle(query);
ctx.query_ = query;
ctx.ia_rsp_ = ia_rsp;
ctx.hwaddr_ = orig_ctx.hwaddr_;
ctx.host_ = orig_ctx.host_;
ctx.createIAContext();
ctx.currentIA().iaid_ = ia->getIAID();
ctx.currentIA().type_ = Lease::TYPE_PD;
ctx.currentIA().ia_rsp_ = ia_rsp;
// Extract prefixes that the client is trying to renew.
OptionCollection addrs = ia->getOptions();
......@@ -1759,7 +1748,7 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
}
// Put the client's prefix into the hints list.
ctx.hints_.push_back(make_pair(prf->getAddress(), prf->getLength()));
ctx.currentIA().addHint(prf->getAddress(), prf->getLength());
}
// Call Allocation Engine and attempt to renew leases. Number of things
......@@ -1772,6 +1761,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
// in PD context)
Lease6Collection leases = alloc_engine_->renewLeases6(ctx);
AllocEngine::HintContainer hints = ctx.currentIA().hints_;
// For all the leases we have now, add the IAPPREFIX with non-zero lifetimes
for (Lease6Collection::const_iterator l = leases.begin(); l != leases.end(); ++l) {
Option6IAPrefixPtr prf(new Option6IAPrefix(D6O_IAPREFIX,
......@@ -1785,9 +1776,9 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
.arg(ia->getIAID());
// Now remove this address from the hints list.
AllocEngine::HintType tmp((*l)->addr_, (*l)->prefixlen_);
ctx.hints_.erase(std::remove(ctx.hints_.begin(), ctx.hints_.end(), tmp),
ctx.hints_.end());
AllocEngine::HintType hint_type((*l)->addr_, (*l)->prefixlen_);
hints.erase(std::remove(hints.begin(), hints.end(), hint_type),
hints.end());
}
/// @todo: Maybe we should iterate over ctx.old_leases_, i.e. the leases
......@@ -1797,8 +1788,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
// zero lifetimes
// Finally, if there are any addresses requested that we haven't dealt with
// already, inform the client that he can't have them.
for (AllocEngine::HintContainer::const_iterator prefix = ctx.hints_.begin();
prefix != ctx.hints_.end(); ++prefix) {
for (AllocEngine::HintContainer::const_iterator prefix = hints.begin();
prefix != hints.end(); ++prefix) {
// Send the prefix with the zero lifetimes only if the prefix
// contains non-zero value. A zero value indicates that the hint was
// for the prefix length.
......@@ -2238,7 +2229,8 @@ Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
sanityCheck(solicit, MANDATORY, FORBIDDEN);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(solicit);
AllocEngine::ClientContext6 ctx;
initContext(solicit, ctx);
Pkt6Ptr response(new Pkt6(DHCPV6_ADVERTISE, solicit->getTransid()));
......@@ -2282,7 +2274,8 @@ Dhcpv6Srv::processRequest(const Pkt6Ptr& request) {
sanityCheck(request, MANDATORY, MANDATORY);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(request);
AllocEngine::ClientContext6 ctx;
initContext(request, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, request->getTransid()));
......@@ -2307,7 +2300,8 @@ Dhcpv6Srv::processRenew(const Pkt6Ptr& renew) {
sanityCheck(renew, MANDATORY, MANDATORY);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(renew);
AllocEngine::ClientContext6 ctx;
initContext(renew, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, renew->getTransid()));
......@@ -2331,7 +2325,8 @@ Dhcpv6Srv::processRebind(const Pkt6Ptr& rebind) {
sanityCheck(rebind, MANDATORY, FORBIDDEN);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(rebind);
AllocEngine::ClientContext6 ctx;
initContext(rebind, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, rebind->getTransid()));
......@@ -2355,7 +2350,8 @@ Dhcpv6Srv::processConfirm(const Pkt6Ptr& confirm) {
sanityCheck(confirm, MANDATORY, FORBIDDEN);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(confirm);
AllocEngine::ClientContext6 ctx;
initContext(confirm, ctx);
// Get IA_NAs from the Confirm. If there are none, the message is
// invalid and must be discarded. There is nothing more to do.
......@@ -2445,7 +2441,8 @@ Dhcpv6Srv::processRelease(const Pkt6Ptr& release) {
sanityCheck(release, MANDATORY, MANDATORY);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(release);
AllocEngine::ClientContext6 ctx;
initContext(release, ctx);
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, release->getTransid()));
......@@ -2472,7 +2469,8 @@ Dhcpv6Srv::processDecline(const Pkt6Ptr& decline) {
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, decline->getTransid()));
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(decline);
AllocEngine::ClientContext6 ctx;
initContext(decline, ctx);
// Copy client options (client-id, also relay information if present)
copyClientOptions(decline, reply);
......@@ -2748,7 +2746,8 @@ Dhcpv6Srv::processInfRequest(const Pkt6Ptr& inf_request) {
sanityCheck(inf_request, OPTIONAL, OPTIONAL);
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx = createContext(inf_request);
AllocEngine::ClientContext6 ctx;
initContext(inf_request, ctx);
// Create a Reply packet, with the same trans-id as the client's.
Pkt6Ptr reply(new Pkt6(DHCPV6_REPLY, inf_request->getTransid()));
......
......@@ -307,13 +307,13 @@ protected:
/// @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 orig_ctx client context (contains subnet, duid and other parameters)
/// @param ctx client context (contains subnet, duid and other parameters)
/// @param ia pointer to client's IA_NA option (client's request)
///
/// @return IA_NA option (server's response)
OptionPtr assignIA_NA(const isc::dhcp::Pkt6Ptr& query,
const isc::dhcp::Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
Option6IAPtr ia);
/// @brief Processes IA_PD option (and assigns prefixes if necessary).
......@@ -326,12 +326,12 @@ protected:
///
/// @param query client's message (typically SOLICIT or REQUEST)
/// @param answer server's response to the client's message.
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ctx client context (contains subnet, duid and other parameters)
/// @param ia pointer to client's IA_PD option (client's request)
/// @return IA_PD option (server's response)
OptionPtr assignIA_PD(const Pkt6Ptr& query,
const isc::dhcp::Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
boost::shared_ptr<Option6IA> ia);
/// @brief Extends lifetime of the specific IA_NA option.
......@@ -357,12 +357,12 @@ protected:
/// @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 orig_ctx client context (contains subnet, duid and other parameters)
/// @param ctx client context (contains subnet, duid and other parameters)
/// @param ia IA_NA option which carries address for which lease lifetime
/// will be extended.
/// @return IA_NA option (server's response)
OptionPtr extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
Option6IAPtr ia);
/// @brief Extends lifetime of the prefix.
......@@ -377,14 +377,14 @@ protected:
/// (see RFC3633, section 12.2. for details).
///
/// @param query client's message
/// @param orig_ctx client context (contains subnet, duid and other parameters)
/// @param ctx client context (contains subnet, duid and other parameters)
/// @param ia IA_PD option that is being renewed
/// @return IA_PD option (server's response)
/// @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 Pkt6Ptr& query,
AllocEngine::ClientContext6& orig_ctx,
AllocEngine::ClientContext6& ctx,
Option6IAPtr ia);
/// @brief Releases specific IA_NA option
......@@ -656,9 +656,9 @@ protected:
/// - there is no such option provided by the server)
void processRSOO(const Pkt6Ptr& query, const Pkt6Ptr& rsp);
/// @brief Creates client context for specified packet
/// @brief Initializes client context for specified packet
///
/// Instantiates the ClientContext6 and then:
/// This method:
/// - Performs the subnet selection and stores the result in context
/// - Extracts the duid from the packet and saves it to the context
/// - Extracts the hardware address from the packet and saves it to
......@@ -666,8 +666,9 @@ protected:
/// - Performs host reservation lookup and stores the result in the
/// context
///
/// @return client context
AllocEngine::ClientContext6 createContext(const Pkt6Ptr& pkt);
/// @param pkt pointer to a packet for which context will be created.
/// @param [out] ctx reference to context object to be initialized.
void initContext(const Pkt6Ptr& pkt, AllocEngine::ClientContext6& ctx);
/// @brief this is a prefix added to the contend of vendor-class option
///
......
......@@ -131,7 +131,7 @@ public:
using Dhcpv6Srv::shutdown_;
using Dhcpv6Srv::name_change_reqs_;
using Dhcpv6Srv::VENDOR_CLASS_PREFIX;
using Dhcpv6Srv::createContext;
using Dhcpv6Srv::initContext;
/// @brief packets we pretend to receive
///
......
......@@ -35,6 +35,7 @@
#include <vector>
#include <stdint.h>
#include <string.h>
#include <utility>
using namespace isc::asiolink;
using namespace isc::dhcp;
......@@ -331,31 +332,24 @@ AllocEngine::findReservationInternal(ContextType& ctx,
// ##########################################################################
AllocEngine::ClientContext6::ClientContext6()
: subnet_(), duid_(), iaid_(0), type_(Lease::TYPE_NA), hwaddr_(),
hints_(), fwd_dns_update_(false), rev_dns_update_(false), hostname_(""),
callout_handle_(), fake_allocation_(false), old_leases_(), host_(),
query_(), ia_rsp_(), host_identifiers_() {
: query_(), fake_allocation_(false), subnet_(), duid_(),
hwaddr_(), host_identifiers_(), host_(), fwd_dns_update_(false),
rev_dns_update_(false), hostname_(), callout_handle_(),
ias_() {
}
AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const DuidPtr& duid,
const uint32_t iaid,
const isc::asiolink::IOAddress& hint,
const Lease::Type type, const bool fwd_dns,
AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet,
const DuidPtr& duid,
const bool fwd_dns,
const bool rev_dns,
const std::string& hostname,
const bool fake_allocation):
subnet_(subnet), duid_(duid), iaid_(iaid), type_(type), hwaddr_(),
hints_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
hostname_(hostname), fake_allocation_(fake_allocation),
old_leases_(), host_(), query_(), ia_rsp_(), host_identifiers_() {
static asiolink::IOAddress any("::");
if (hint != any) {
hints_.push_back(std::make_pair(hint, 128));
}
// callout_handle, host pointers initiated to NULL by their
// respective constructors.
const bool fake_allocation,
const Pkt6Ptr& query,
const CalloutHandlePtr& callout_handle)
: query_(query), fake_allocation_(fake_allocation), subnet_(subnet),
duid_(duid), hwaddr_(), host_identifiers_(), host_(),
fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
hostname_(hostname), callout_handle_(callout_handle), ias_() {
// Initialize host identifiers.
if (duid) {
......@@ -363,6 +357,17 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const Duid
}
}
AllocEngine::ClientContext6::IAContext::IAContext()
: iaid_(0), type_(Lease::TYPE_NA), hints_(), old_leases_(),
changed_leases_(), ia_rsp_() {
}
void
AllocEngine::ClientContext6::
IAContext::addHint(const asiolink::IOAddress& prefix,
const uint8_t prefix_len) {
hints_.push_back(std::make_pair(prefix, prefix_len));
}
void AllocEngine::findReservation(ClientContext6& ctx) {
findReservationInternal(ctx, boost::bind(&HostMgr::get6,
......@@ -384,7 +389,9 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
// Check if there are existing leases for that subnet/duid/iaid
// combination.
Lease6Collection leases =
LeaseMgrFactory::instance().getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_,
LeaseMgrFactory::instance().getLeases6(ctx.currentIA().type_,
*ctx.duid_,
ctx.currentIA().iaid_,
ctx.subnet_->getID());
// Now do the checks:
......@@ -544,11 +551,11 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
Lease6Collection
AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
AllocatorPtr allocator = getAllocator(ctx.type_);
AllocatorPtr allocator = getAllocator(ctx.currentIA().type_);
if (!allocator) {
isc_throw(InvalidOperation, "No allocator specified for "
<< Lease6::typeToText(ctx.type_));
<< Lease6::typeToText(ctx.currentIA().type_));
}
// Check which host reservation mode is supported in this subnet.
......@@ -557,19 +564,20 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
Lease6Collection leases;
IOAddress hint = IOAddress::IPV6_ZERO_ADDRESS();
if (!ctx.hints_.empty()) {
if (!ctx.currentIA().hints_.empty()) {
/// @todo: We support only one hint for now
hint = ctx.hints_[0].first;
hint = ctx.currentIA().hints_[0].first;
}
// check if the hint is in pool and is available
// This is equivalent of subnet->inPool(hint), but returns the pool
Pool6Ptr pool = boost::dynamic_pointer_cast<
Pool6>(ctx.subnet_->getPool(ctx.type_, hint, false));
Pool6>(ctx.subnet_->getPool(ctx.currentIA().type_, hint, false));
if (pool) {
/// @todo: We support only one hint for now
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(ctx.type_, hint);
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(ctx.currentIA().type_,
hint);
if (!lease) {
// In-pool reservations: Check if this address is reserved for someone
......@@ -623,7 +631,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
// Copy an existing, expired lease so as it can be returned
// to the caller.
Lease6Ptr old_lease(new Lease6(*lease));
ctx.old_leases_.push_back(old_lease);
ctx.currentIA().old_leases_.push_back(old_lease);
/// We found a lease and it is expired, so we can reuse it
lease = reuseExpiredLease(lease, ctx, pool->getLength());
......@@ -649,7 +657,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
// - we find an address for which the lease has expired
// - we exhaust number of tries
uint64_t max_attempts = (attempts_ > 0 ? attempts_ :
ctx.subnet_->getPoolCapacity(ctx.type_));
ctx.subnet_->getPoolCapacity(ctx.currentIA().type_));
for (uint64_t i = 0; i < max_attempts; ++i)
{
IOAddress candidate = allocator->pickAddress(ctx.subnet_, ctx.duid_, hint);
......@@ -667,14 +675,14 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
// The first step is to find out prefix length. It is 128 for
// non-PD leases.
uint8_t prefix_len = 128;
if (ctx.type_ == Lease::TYPE_PD) {
if (ctx.currentIA().type_ == Lease::TYPE_PD) {
Pool6Ptr pool = boost::dynamic_pointer_cast<Pool6>(
ctx.subnet_->getPool(ctx.type_, candidate, false));
ctx.subnet_->getPool(ctx.currentIA().type_, candidate, false));
/// @todo: verify that the pool is non-null
prefix_len = pool->getLength();
}
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(ctx.type_,
Lease6Ptr existing = LeaseMgrFactory::instance().getLease6(ctx.currentIA().type_,