|
@@ -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()));
|