31 #include <boost/foreach.hpp>
51 struct AllocEngineHooks {
52 int hook_index_lease4_select_;
53 int hook_index_lease4_renew_;
54 int hook_index_lease4_expire_;
55 int hook_index_lease4_recover_;
56 int hook_index_lease6_select_;
57 int hook_index_lease6_renew_;
58 int hook_index_lease6_rebind_;
59 int hook_index_lease6_expire_;
60 int hook_index_lease6_recover_;
64 hook_index_lease4_select_ = HooksManager::registerHook(
"lease4_select");
65 hook_index_lease4_renew_ = HooksManager::registerHook(
"lease4_renew");
66 hook_index_lease4_expire_ = HooksManager::registerHook(
"lease4_expire");
67 hook_index_lease4_recover_= HooksManager::registerHook(
"lease4_recover");
68 hook_index_lease6_select_ = HooksManager::registerHook(
"lease6_select");
69 hook_index_lease6_renew_ = HooksManager::registerHook(
"lease6_renew");
70 hook_index_lease6_rebind_ = HooksManager::registerHook(
"lease6_rebind");
71 hook_index_lease6_expire_ = HooksManager::registerHook(
"lease6_expire");
72 hook_index_lease6_recover_= HooksManager::registerHook(
"lease6_recover");
80 AllocEngineHooks
Hooks;
87 AllocEngine::IterativeAllocator::IterativeAllocator(
Lease::Type lease_type)
93 const uint8_t prefix_len) {
96 "increase prefix " << prefix <<
")");
100 const std::vector<uint8_t>& vec = prefix.
toBytes();
102 if (prefix_len < 1 || prefix_len > 128) {
110 uint8_t n_bytes = (prefix_len - 1)/8;
111 uint8_t n_bits = 8 - (prefix_len - n_bytes*8);
112 uint8_t mask = 1 << n_bits;
121 uint8_t packed[V6ADDRESS_LEN];
124 std::memcpy(packed, &vec[0], V6ADDRESS_LEN);
127 if (packed[n_bytes] + uint16_t(mask) < 256u) {
128 packed[n_bytes] += mask;
133 packed[n_bytes] += mask;
136 for (
int i = n_bytes - 1; i >= 0; --i) {
139 if (packed[i] != 0) {
150 const uint8_t prefix_len) {
154 return (increasePrefix(address, prefix_len));
166 uint8_t prefix_len = 0;
171 IOAddress last = subnet->getLastAllocated(pool_type_);
173 bool retrying =
false;
182 PoolCollection::const_iterator it;
183 PoolCollection::const_iterator first = pools.end();
185 for (it = pools.begin(); it != pools.end(); ++it) {
186 if (!(*it)->clientSupported(client_classes)) {
189 if (first == pools.end()) {
192 if ((*it)->inRange(last)) {
198 if (first == pools.end()) {
207 if (it == pools.end()) {
214 for (; it != pools.end(); ++it) {
215 if ((*it)->clientSupported(client_classes)) {
219 if (it == pools.end()) {
225 last = (*it)->getLastAllocated();
226 valid = (*it)->isLastAllocatedValid();
227 if (!valid && (last == (*it)->getFirstAddress())) {
229 (*it)->setLastAllocated(last);
230 subnet->setLastAllocated(pool_type_, last);
234 if (valid && !(*it)->inRange(last)) {
236 (*it)->resetLastAllocated();
237 (*it)->setLastAllocated((*it)->getFirstAddress());
243 Pool6Ptr pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
252 prefix_len = pool6->getLength();
255 IOAddress next = increaseAddress(last, prefix, prefix_len);
256 if ((*it)->inRange(next)) {
259 (*it)->setLastAllocated(next);
260 subnet->setLastAllocated(pool_type_, next);
265 (*it)->resetLastAllocated();
273 for (it = first; it != pools.end(); ++it) {
274 if ((*it)->clientSupported(client_classes)) {
275 (*it)->setLastAllocated((*it)->getFirstAddress());
276 (*it)->resetLastAllocated();
281 last = (*first)->getLastAllocated();
282 (*first)->setLastAllocated(last);
283 subnet->setLastAllocated(pool_type_, last);
318 : attempts_(attempts), incomplete_v4_reclamations_(0),
319 incomplete_v6_reclamations_(0) {
325 switch (engine_type) {
342 switch (engine_type) {
361 hook_index_lease4_select_ =
Hooks.hook_index_lease4_select_;
362 hook_index_lease6_select_ =
Hooks.hook_index_lease6_select_;
366 std::map<Lease::Type, AllocatorPtr>::const_iterator alloc = allocators_.find(type);
368 if (alloc == allocators_.end()) {
372 return (alloc->second);
394 const IOAddress& address,
bool check_subnet) {
398 while (current_subnet) {
400 if (current_subnet->clientSupported(ctx.
query_->getClasses())) {
402 if (current_subnet->inPool(lease_type, address)) {
406 if (current_subnet->inPool(lease_type, address,
407 ctx.
query_->getClasses())) {
413 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
430 : query_(), fake_allocation_(false), subnet_(), host_subnet_(), duid_(),
431 hwaddr_(), host_identifiers_(), hosts_(), fwd_dns_update_(false),
432 rev_dns_update_(false), hostname_(), callout_handle_(), ias_() {
439 const std::string& hostname,
440 const bool fake_allocation,
443 : query_(query), fake_allocation_(fake_allocation), subnet_(subnet),
444 duid_(duid), hwaddr_(), host_identifiers_(), hosts_(),
445 fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), hostname_(hostname),
446 callout_handle_(callout_handle), allocated_resources_(), new_leases_(),
456 : iaid_(0), type_(
Lease::TYPE_NA), hints_(), old_leases_(),
457 changed_leases_(), ia_rsp_() {
463 const uint8_t prefix_len) {
464 hints_.push_back(std::make_pair(prefix, prefix_len));
470 const uint8_t prefix_len) {
478 return (
static_cast<bool>
487 SUBNET_ID_GLOBAL : subnet->getID());
489 auto host =
hosts_.find(
id);
490 if (host !=
hosts_.cend()) {
491 return (host->second);
502 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
503 if (host !=
hosts_.cend()) {
504 return (host->second);
514 return (ghost && ghost->hasReservation(resv));
527 std::map<SubnetID, ConstHostPtr> host_map;
529 subnet->getSharedNetwork(network);
534 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
547 const bool use_single_query = network &&
550 if (use_single_query) {
554 id_pair.second.size());
558 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
559 if ((*host)->getIPv6SubnetID()) {
560 host_map[(*host)->getIPv6SubnetID()] = *host;
571 if (subnet->clientSupported(ctx.
query_->getClasses()) &&
576 if (use_single_query) {
577 if (host_map.count(subnet->getID()) > 0) {
578 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
586 id_pair.second.size());
589 ctx.
hosts_[subnet->getID()] = host;
600 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
610 &id_pair.second[0], id_pair.second.size());
645 for (
auto l : all_leases) {
646 if ((l)->subnet_id_ == subnet->getID()) {
651 subnet = subnet->getNextSubnet(ctx.
subnet_);
671 if (leases.empty() && !ctx.
hosts_.empty()) {
674 ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR)
675 .arg(ctx.
query_->getLabel());
680 allocateReservedLeases6(ctx, leases);
695 }
else if (!leases.empty() && ctx.
hosts_.empty()) {
698 ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR)
699 .arg(ctx.
query_->getLabel());
703 removeNonmatchingReservedLeases6(ctx, leases);
705 leases = updateLeaseData(ctx, leases);
714 }
else if (!leases.empty() && !ctx.
hosts_.empty()) {
717 ALLOC_ENGINE_V6_ALLOC_LEASES_HR)
718 .arg(ctx.
query_->getLabel());
722 allocateReservedLeases6(ctx, leases);
734 removeNonmatchingReservedLeases6(ctx, leases);
743 removeNonreservedLeases6(ctx, leases);
758 if (leases.empty()) {
771 ALLOC_ENGINE_V6_ALLOC_UNRESERVED)
772 .arg(ctx.
query_->getLabel());
774 leases = allocateUnreservedLeases6(ctx);
777 if (!leases.empty()) {
793 .arg(ctx.
query_->getLabel())
813 if (!ctx.currentIA().hints_.empty()) {
815 hint = ctx.currentIA().hints_[0].first;
827 if (!subnet->clientSupported(ctx.query_->getClasses())) {
828 subnet = subnet->getNextSubnet(original_subnet);
832 ctx.subnet_ = subnet;
836 pool = boost::dynamic_pointer_cast<Pool6>
837 (subnet->getPool(ctx.currentIA().type_, ctx.query_->getClasses(),
841 if (pool && !pool->clientSupported(ctx.query_->getClasses())) {
870 lease = createLease6(ctx, hint, pool->getLength(), callout_status);
880 collection.push_back(lease);
885 ALLOC_ENGINE_V6_HINT_RESERVED)
886 .arg(ctx.query_->getLabel())
893 if (lease->expired()) {
906 ctx.currentIA().old_leases_.push_back(old_lease);
909 lease = reuseExpiredLease(lease, ctx, pool->getLength(),
913 leases.push_back(lease);
918 ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED)
919 .arg(ctx.query_->getLabel())
926 subnet = subnet->getNextSubnet(original_subnet);
929 uint64_t total_attempts = 0;
941 original_subnet->getSharedNetwork(network);
948 original_subnet = network->getPreferredSubnet(original_subnet, ctx.currentIA().type_);
951 ctx.subnet_ = subnet = original_subnet;
955 if (!subnet->clientSupported(ctx.query_->getClasses())) {
956 subnet = subnet->getNextSubnet(original_subnet);
966 uint64_t possible_attempts =
967 subnet->getPoolCapacity(ctx.currentIA().type_,
968 ctx.query_->getClasses());
970 if (possible_attempts == 0) {
971 subnet = subnet->getNextSubnet(original_subnet);
974 uint64_t max_attempts = (attempts_ > 0 ? attempts_ : possible_attempts);
980 if (ctx.callout_handle_) {
981 ctx.callout_handle_->setStatus(CalloutHandle::NEXT_STEP_CONTINUE);
984 for (uint64_t i = 0; i < max_attempts; ++i) {
988 IOAddress candidate = allocator->pickAddress(subnet,
989 ctx.query_->getClasses(),
1005 uint8_t prefix_len = 128;
1007 pool = boost::dynamic_pointer_cast<Pool6>(
1008 subnet->getPool(ctx.currentIA().type_,
1009 ctx.query_->getClasses(),
1012 prefix_len = pool->getLength();
1023 ctx.subnet_ = subnet;
1024 Lease6Ptr lease = createLease6(ctx, candidate, prefix_len, callout_status);
1028 ctx.currentIA().old_leases_.clear();
1030 leases.push_back(lease);
1033 }
else if (ctx.callout_handle_ &&
1034 (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
1043 if (existing->expired()) {
1047 ctx.currentIA().old_leases_.push_back(old_lease);
1049 ctx.subnet_ = subnet;
1050 existing = reuseExpiredLease(existing, ctx, prefix_len,
1053 leases.push_back(existing);
1059 subnet = subnet->getNextSubnet(original_subnet);
1064 .arg(ctx.query_->getLabel())
1065 .arg(total_attempts);
1076 if (ctx.hosts_.empty()) {
1078 ALLOC_ENGINE_V6_ALLOC_NO_V6_HR)
1079 .arg(ctx.query_->getLabel());
1083 if (allocateGlobalReservedLeases6(ctx, existing_leases)) {
1095 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1096 if ((lease->valid_lft_ != 0)) {
1097 if ((ctx.hosts_.count(lease->subnet_id_) > 0) &&
1098 ctx.hosts_[lease->subnet_id_]->hasReservation(
makeIPv6Resrv(*lease))) {
1102 ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS)
1103 .arg(ctx.query_->getLabel())
1104 .arg(lease->typeToText(lease->type_))
1105 .arg(lease->addr_.toText());
1111 if (!ctx.host_subnet_) {
1113 ctx.subnet_->getSharedNetwork(network);
1118 ctx.host_subnet_ = network->getSubnet(lease->subnet_id_);
1126 if (host && !host->getHostname().empty()) {
1133 qualifyName(host->getHostname(),
static_cast<bool>(fqdn));
1140 if (!ctx.fake_allocation_ && conditionalExtendLifetime(*lease)) {
1155 SubnetID subnet_id = subnet->getID();
1158 if (!subnet->clientSupported(ctx.query_->getClasses()) ||
1159 ctx.hosts_.count(subnet_id) == 0) {
1160 subnet = subnet->getNextSubnet(ctx.subnet_);
1170 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1171 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1175 if (ctx.isAllocated(addr, prefix_len)) {
1187 ctx.subnet_ = subnet;
1189 if (!ctx.host_subnet_) {
1190 ctx.host_subnet_ = subnet;
1191 if (!host->getHostname().empty()) {
1205 qualifyName(host->getHostname(),
static_cast<bool>(fqdn));
1211 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1214 existing_leases.push_back(lease);
1220 .arg(ctx.query_->getLabel());
1224 .arg(
static_cast<int>(prefix_len))
1225 .arg(ctx.query_->getLabel());
1242 subnet = subnet->getNextSubnet(ctx.subnet_);
1258 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1259 if ((lease->valid_lft_ != 0) &&
1264 ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS)
1265 .arg(ctx.query_->getLabel())
1266 .arg(lease->typeToText(lease->type_))
1267 .arg(lease->addr_.toText());
1273 if (!ghost->getHostname().empty()) {
1280 qualifyName(ghost->getHostname(),
static_cast<bool>(fqdn));
1285 if (!ctx.fake_allocation_ && conditionalExtendLifetime(*lease)) {
1300 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1303 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1304 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1308 if (ctx.isAllocated(addr, prefix_len)) {
1316 if (!ghost->getHostname().empty()) {
1330 qualifyName(ghost->getHostname(),
static_cast<bool>(fqdn));
1335 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1338 existing_leases.push_back(lease);
1343 .arg(ctx.query_->getLabel());
1347 .arg(
static_cast<int>(prefix_len))
1348 .arg(ctx.query_->getLabel());
1368 AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1371 if (existing_leases.empty() || !ctx.subnet_) {
1377 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1390 if ((ctx.hasGlobalReservation(resv)) ||
1391 ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
1392 (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1407 if (!host && inAllowedPool(ctx, candidate->type_,
1408 candidate->addr_,
false)) {
1417 .arg(candidate->addr_.toText()).arg(ctx.duid_->toText())
1418 .arg(host->getIdentifierAsText());
1421 .arg(candidate->addr_.toText())
1422 .arg(
static_cast<int>(candidate->prefixlen_))
1423 .arg(ctx.duid_->toText())
1424 .arg(host->getIdentifierAsText());
1436 StatsMgr::instance().addValue(
1437 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1439 "assigned-nas" :
"assigned-pds"),
1440 static_cast<int64_t
>(-1));
1448 ctx.currentIA().old_leases_.push_back(candidate);
1451 removeLeases(existing_leases, candidate->addr_);
1456 AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1467 if (inAllowedPool(ctx, candidate->type_,
1468 candidate->addr_,
false)) {
1479 StatsMgr::instance().addValue(
1480 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1482 "assigned-nas" :
"assigned-pds"),
1483 static_cast<int64_t
>(-1));
1486 ctx.currentIA().old_leases_.push_back(candidate);
1489 removeLeases(existing_leases, candidate->addr_);
1494 AllocEngine::removeLeases(
Lease6Collection& container,
const asiolink::IOAddress& addr) {
1496 bool removed =
false;
1497 for (Lease6Collection::iterator lease = container.begin();
1498 lease != container.end(); ++lease) {
1499 if ((*lease)->addr_ == addr) {
1506 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1517 if (existing_leases.empty()) {
1522 int total = existing_leases.size();
1526 for (Lease6Collection::iterator lease = existing_leases.begin();
1527 lease != existing_leases.end(); ++lease) {
1531 if (ctx.hasGlobalReservation(resv) ||
1532 ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
1533 (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1545 StatsMgr::instance().addValue(
1546 StatsMgr::generateName(
"subnet", (*lease)->subnet_id_,
1548 "assigned-nas" :
"assigned-pds"),
1549 static_cast<int64_t
>(-1));
1554 ctx.currentIA().old_leases_.push_back(*lease);
1570 existing_leases.erase(std::remove(existing_leases.begin(),
1571 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1579 if (!expired->expired()) {
1580 isc_throw(BadValue,
"Attempt to recycle lease that is still valid");
1587 if (!ctx.fake_allocation_) {
1591 reclaimExpiredLease(expired, ctx.callout_handle_);
1595 expired->iaid_ = ctx.currentIA().iaid_;
1596 expired->duid_ = ctx.duid_;
1597 expired->preferred_lft_ = ctx.subnet_->getPreferred();
1598 expired->valid_lft_ = ctx.subnet_->getValid();
1599 expired->t1_ = ctx.subnet_->getT1();
1600 expired->t2_ = ctx.subnet_->getT2();
1601 expired->cltt_ = time(NULL);
1602 expired->subnet_id_ = ctx.subnet_->getID();
1603 expired->hostname_ = ctx.hostname_;
1604 expired->fqdn_fwd_ = ctx.fwd_dns_update_;
1605 expired->fqdn_rev_ = ctx.rev_dns_update_;
1606 expired->prefixlen_ = prefix_len;
1610 ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA)
1611 .arg(ctx.query_->getLabel())
1612 .arg(expired->toText());
1615 if (ctx.callout_handle_ &&
1616 HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
1630 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1633 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1636 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1639 ctx.callout_handle_->setArgument(
"lease6", expired);
1642 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.callout_handle_);
1644 callout_status = ctx.callout_handle_->getStatus();
1649 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
1661 ctx.callout_handle_->getArgument(
"lease6", expired);
1664 if (!ctx.fake_allocation_) {
1670 if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
1671 StatsMgr::instance().addValue(
1672 StatsMgr::generateName(
"subnet", ctx.subnet_->getID(),
1674 "assigned-nas" :
"assigned-pds"),
1675 static_cast<int64_t
>(1));
1697 ctx.currentIA().iaid_, ctx.subnet_->getPreferred(),
1698 ctx.subnet_->getValid(), ctx.subnet_->getT1(),
1699 ctx.subnet_->getT2(), ctx.subnet_->getID(),
1700 ctx.hwaddr_, prefix_len));
1702 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
1703 lease->fqdn_rev_ = ctx.rev_dns_update_;
1704 lease->hostname_ = ctx.hostname_;
1707 if (ctx.callout_handle_ &&
1708 HooksManager::getHooksManager().calloutsPresent(hook_index_lease6_select_)) {
1722 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1725 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1728 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1729 ctx.callout_handle_->setArgument(
"lease6", lease);
1732 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.callout_handle_);
1734 callout_status = ctx.callout_handle_->getStatus();
1739 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
1746 ctx.callout_handle_->getArgument(
"lease6", lease);
1749 if (!ctx.fake_allocation_) {
1756 if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
1757 StatsMgr::instance().addValue(
1758 StatsMgr::generateName(
"subnet", ctx.subnet_->getID(),
1760 "assigned-nas" :
"assigned-pds"),
1761 static_cast<int64_t
>(1));
1778 ctx.currentIA().type_, addr);
1807 leases.insert(leases.end(), leases_subnet.begin(), leases_subnet.end());
1809 subnet = subnet->getNextSubnet(ctx.
subnet_);
1813 if (!leases.empty()) {
1815 ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED)
1816 .arg(ctx.
query_->getLabel());
1820 removeNonmatchingReservedLeases6(ctx, leases);
1823 if (!ctx.
hosts_.empty()) {
1826 ALLOC_ENGINE_V6_RENEW_HR)
1827 .arg(ctx.
query_->getLabel());
1830 allocateReservedLeases6(ctx, leases);
1836 removeNonreservedLeases6(ctx, leases);
1843 if (leases.empty()) {
1846 ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED)
1847 .arg(ctx.
query_->getLabel());
1849 leases = allocateUnreservedLeases6(ctx);
1853 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
1855 ALLOC_ENGINE_V6_EXTEND_LEASE)
1856 .arg(ctx.
query_->getLabel())
1857 .arg((*l)->typeToText((*l)->type_))
1859 extendLease6(ctx, *l);
1862 if (!leases.empty()) {
1866 BOOST_FOREACH(
Lease6Ptr lease, leases) {
1878 .arg(ctx.
query_->getLabel())
1888 if (!lease || !ctx.subnet_) {
1894 if (ctx.subnet_->getID() != lease->subnet_id_) {
1896 ctx.subnet_->getSharedNetwork(network);
1902 ctx.subnet_ = subnet;
1910 (((lease->type_ !=
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
1911 !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
1921 StatsMgr::instance().addValue(
1922 StatsMgr::generateName(
"subnet", ctx.subnet_->getID(),
"assigned-nas"),
1923 static_cast<int64_t
>(-1));
1926 ctx.currentIA().old_leases_.push_back(lease);
1932 ALLOC_ENGINE_V6_EXTEND_LEASE_DATA)
1933 .arg(ctx.query_->getLabel())
1934 .arg(lease->toText());
1939 lease->preferred_lft_ = ctx.subnet_->getPreferred();
1940 lease->valid_lft_ = ctx.subnet_->getValid();
1941 lease->t1_ = ctx.subnet_->getT1();
1942 lease->t2_ = ctx.subnet_->getT2();
1943 lease->hostname_ = ctx.hostname_;
1944 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
1945 lease->fqdn_rev_ = ctx.rev_dns_update_;
1946 lease->hwaddr_ = ctx.hwaddr_;
1950 conditionalExtendLifetime(*lease);
1953 ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA)
1954 .arg(ctx.query_->getLabel())
1955 .arg(lease->toText());
1959 int hook_point = ctx.query_->getType() ==
DHCPV6_RENEW ?
1960 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
1961 if (HooksManager::calloutsPresent(hook_point)) {
1974 callout_handle->setArgument(
"query6", ctx.query_);
1977 callout_handle->setArgument(
"lease6", lease);
1981 callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
1983 callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
1987 HooksManager::callCallouts(hook_point, *callout_handle);
1992 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
1995 DHCPSRV_HOOK_LEASE6_EXTEND_SKIP)
1996 .arg(ctx.query_->getName());
2005 if (old_data->expired()) {
2006 reclaimExpiredLease(old_data, ctx.callout_handle_);
2010 if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
2011 StatsMgr::instance().addValue(
2012 StatsMgr::generateName(
"subnet", ctx.subnet_->getID(),
2014 "assigned-nas" :
"assigned-pds"),
2015 static_cast<int64_t
>(1));
2018 if (!lease->hasIdenticalFqdn(*old_data)) {
2039 ctx.currentIA().changed_leases_.push_back(old_data);
2046 bool remove_queued =
false;
2047 for (Lease6Collection::const_iterator lease_it = leases.begin();
2048 lease_it != leases.end(); ++lease_it) {
2050 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2051 lease->fqdn_rev_ = ctx.rev_dns_update_;
2052 lease->hostname_ = ctx.hostname_;
2053 if (!ctx.fake_allocation_) {
2061 if (inAllowedPool(ctx, ctx.currentIA().type_,
2062 lease->addr_,
true)) {
2063 StatsMgr::instance().addValue(
2064 StatsMgr::generateName(
"subnet", lease->subnet_id_,
2066 "assigned-nas" :
"assigned-pds"),
2067 static_cast<int64_t
>(1));
2072 !(lease->hasIdenticalFqdn(**lease_it)));
2074 if (conditionalExtendLifetime(*lease) || fqdn_changed) {
2075 ctx.currentIA().changed_leases_.push_back(*lease_it);
2080 if (fqdn_changed && !remove_queued) {
2082 remove_queued =
true;
2087 updated_leases.push_back(lease);
2090 return (updated_leases);
2095 const bool remove_lease,
2096 const uint16_t max_unwarned_cycles) {
2099 ALLOC_ENGINE_V6_LEASES_RECLAMATION_START)
2111 bool incomplete_reclamation =
false;
2114 if (max_leases > 0) {
2123 if (leases.size() > max_leases) {
2125 incomplete_reclamation =
true;
2138 if (!leases.empty() &&
2139 HooksManager::getHooksManager().calloutsPresent(
Hooks.hook_index_lease6_expire_)) {
2140 callout_handle = HooksManager::createCalloutHandle();
2143 size_t leases_processed = 0;
2144 BOOST_FOREACH(
Lease6Ptr lease, leases) {
2148 reclaimExpiredLease(lease, remove_lease, callout_handle);
2151 }
catch (
const std::exception& ex) {
2153 .arg(lease->addr_.toText())
2164 if (!incomplete_reclamation) {
2165 if (leases_processed < leases.size()) {
2166 incomplete_reclamation =
true;
2171 ALLOC_ENGINE_V6_LEASES_RECLAMATION_TIMEOUT)
2182 ALLOC_ENGINE_V6_LEASES_RECLAMATION_COMPLETE)
2183 .arg(leases_processed)
2188 if (incomplete_reclamation) {
2189 ++incomplete_v6_reclamations_;
2192 if ((max_unwarned_cycles > 0) &&
2193 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2195 .arg(max_unwarned_cycles);
2197 incomplete_v6_reclamations_ = 0;
2202 incomplete_v6_reclamations_ = 0;
2205 ALLOC_ENGINE_V6_NO_MORE_EXPIRED_LEASES);
2212 ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE)
2215 uint64_t deleted_leases = 0;
2221 }
catch (
const std::exception& ex) {
2227 ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_COMPLETE)
2228 .arg(deleted_leases);
2234 const bool remove_lease,
2235 const uint16_t max_unwarned_cycles) {
2238 ALLOC_ENGINE_V4_LEASES_RECLAMATION_START)
2250 bool incomplete_reclamation =
false;
2253 if (max_leases > 0) {
2262 if (leases.size() > max_leases) {
2264 incomplete_reclamation =
true;
2278 if (!leases.empty() &&
2279 HooksManager::getHooksManager().calloutsPresent(
Hooks.hook_index_lease4_expire_)) {
2280 callout_handle = HooksManager::createCalloutHandle();
2283 size_t leases_processed = 0;
2284 BOOST_FOREACH(
Lease4Ptr lease, leases) {
2288 reclaimExpiredLease(lease, remove_lease, callout_handle);
2291 }
catch (
const std::exception& ex) {
2293 .arg(lease->addr_.toText())
2304 if (!incomplete_reclamation) {
2305 if (leases_processed < leases.size()) {
2306 incomplete_reclamation =
true;
2311 ALLOC_ENGINE_V4_LEASES_RECLAMATION_TIMEOUT)
2322 ALLOC_ENGINE_V4_LEASES_RECLAMATION_COMPLETE)
2323 .arg(leases_processed)
2328 if (incomplete_reclamation) {
2329 ++incomplete_v4_reclamations_;
2332 if ((max_unwarned_cycles > 0) &&
2333 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
2335 .arg(max_unwarned_cycles);
2337 incomplete_v4_reclamations_ = 0;
2342 incomplete_v4_reclamations_ = 0;
2345 ALLOC_ENGINE_V4_NO_MORE_EXPIRED_LEASES);
2349 template<
typename LeasePtrType>
2351 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
2353 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
2357 template<
typename LeasePtrType>
2359 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
2364 if (!lease->stateExpiredReclaimed()) {
2365 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
2370 AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
2371 const DbReclaimMode& reclaim_mode,
2375 ALLOC_ENGINE_V6_LEASE_RECLAIM)
2377 .arg(lease->addr_.toText())
2378 .arg(
static_cast<int>(lease->prefixlen_));
2384 bool skipped =
false;
2385 if (callout_handle) {
2393 callout_handle->deleteAllArguments();
2394 callout_handle->setArgument(
"lease6", lease);
2395 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2397 HooksManager::callCallouts(
Hooks.hook_index_lease6_expire_,
2400 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2415 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2425 remove_lease = reclaimDeclined(lease);
2428 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2432 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
2443 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2450 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2458 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2461 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2463 "reclaimed-leases"),
2468 AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
2469 const DbReclaimMode& reclaim_mode,
2473 ALLOC_ENGINE_V4_LEASE_RECLAIM)
2475 .arg(lease->addr_.toText());
2481 bool skipped =
false;
2482 if (callout_handle) {
2490 callout_handle->setArgument(
"lease4", lease);
2491 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2493 HooksManager::callCallouts(
Hooks.hook_index_lease4_expire_,
2496 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2511 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2521 remove_lease = reclaimDeclined(lease);
2524 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2528 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
2537 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2539 "assigned-addresses"),
2543 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2546 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2548 "reclaimed-leases"),
2555 ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE)
2558 uint64_t deleted_leases = 0;
2564 }
catch (
const std::exception& ex) {
2570 ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_COMPLETE)
2571 .arg(deleted_leases);
2575 AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
2581 if (HooksManager::getHooksManager().calloutsPresent(
Hooks.hook_index_lease4_recover_)) {
2586 if (!callout_handle) {
2587 callout_handle = HooksManager::createCalloutHandle();
2597 callout_handle->setArgument(
"lease4", lease);
2600 HooksManager::callCallouts(
Hooks.hook_index_lease4_recover_, *callout_handle);
2605 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2607 .arg(lease->addr_.toText());
2613 .arg(lease->addr_.toText())
2614 .arg(lease->valid_lft_);
2616 StatsMgr& stats_mgr = StatsMgr::instance();
2619 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2620 "declined-addresses"),
static_cast<int64_t
>(-1));
2623 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
2625 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
2627 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2628 "reclaimed-declined-addresses"),
static_cast<int64_t
>(1));
2636 AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
2642 if (HooksManager::getHooksManager().calloutsPresent(
Hooks.hook_index_lease6_recover_)) {
2647 if (!callout_handle) {
2648 callout_handle = HooksManager::createCalloutHandle();
2658 callout_handle->setArgument(
"lease6", lease);
2661 HooksManager::callCallouts(
Hooks.hook_index_lease6_recover_, *callout_handle);
2666 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2668 .arg(lease->addr_.toText());
2674 .arg(lease->addr_.toText())
2675 .arg(lease->valid_lft_);
2677 StatsMgr& stats_mgr = StatsMgr::instance();
2680 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2681 "declined-addresses"),
static_cast<int64_t
>(-1));
2684 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
2686 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
2688 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2689 "reclaimed-declined-addresses"),
static_cast<int64_t
>(1));
2698 template<
typename LeasePtrType>
2699 void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
2700 const bool remove_lease,
2701 const boost::function<
void (
const LeasePtrType&)>&
2702 lease_update_fun)
const {
2711 }
else if (!lease_update_fun.empty()) {
2714 lease->hostname_.clear();
2715 lease->fqdn_fwd_ =
false;
2716 lease->fqdn_rev_ =
false;
2718 lease_update_fun(lease);
2726 ALLOC_ENGINE_LEASE_RECLAIMED)
2727 .arg(lease->addr_.toText());
2763 if (id->first == host->getIdentifierType()) {
2764 return (id->second != host->getIdentifier());
2790 if (ctx.
hosts_.empty()) {
2797 auto host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
2798 return (host != ctx.
hosts_.end() &&
2799 !(host->second->getIPv4Reservation().isV4Zero()));
2804 auto host = ctx.
hosts_.find(subnet->getID());
2805 if ((host != ctx.
hosts_.end()) &&
2806 !(host->second->getIPv4Reservation().isV4Zero()) &&
2809 (!subnet->inPool(
Lease::TYPE_V4, host->second->getIPv4Reservation()))))) {
2816 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
2858 if (ctx.
clientid_ && subnet->getMatchClientId()) {
2859 for (
auto l = leases_client_id.begin(); l != leases_client_id.end(); ++l) {
2860 if ((*l)->subnet_id_ == subnet->getID()) {
2862 client_lease = (*l);
2871 subnet = subnet->getNextSubnet(original_subnet, ctx.
query_->getClasses());
2877 if (!client_lease && ctx.
hwaddr_) {
2880 subnet = original_subnet;
2887 if (subnet->getMatchClientId()) {
2893 for (Lease4Collection::const_iterator client_lease_it = leases_hw_address.begin();
2894 client_lease_it != leases_hw_address.end(); ++client_lease_it) {
2895 Lease4Ptr existing_lease = *client_lease_it;
2896 if ((existing_lease->subnet_id_ == subnet->getID()) &&
2897 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
2899 client_lease = existing_lease;
2909 subnet = subnet->getNextSubnet(original_subnet, ctx.
query_->getClasses());
2931 while (current_subnet) {
2934 ctx.
query_->getClasses())) {
2942 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_,
2943 ctx.
query_->getClasses());
2955 : subnet_(), clientid_(), hwaddr_(),
2956 requested_address_(
IOAddress::IPV4_ZERO_ADDRESS()),
2957 fwd_dns_update_(false), rev_dns_update_(false),
2958 hostname_(
""), callout_handle_(), fake_allocation_(false),
2959 old_lease_(), new_lease_(), hosts_(), conflicting_lease_(),
2960 query_(), host_identifiers_() {
2967 const bool fwd_dns_update,
2968 const bool rev_dns_update,
2969 const std::string& hostname,
2970 const bool fake_allocation)
2971 : subnet_(subnet), clientid_(clientid), hwaddr_(hwaddr),
2972 requested_address_(requested_addr),
2973 fwd_dns_update_(fwd_dns_update), rev_dns_update_(rev_dns_update),
2974 hostname_(hostname), callout_handle_(),
2975 fake_allocation_(fake_allocation), old_lease_(), new_lease_(),
2976 hosts_(), host_identifiers_() {
2988 SUBNET_ID_GLOBAL : subnet_->getID());
2990 auto host = hosts_.find(
id);
2991 if (host != hosts_.cend()) {
2992 return (host->second);
3012 if (subnet && !subnet->clientSupported(ctx.
query_->getClasses())) {
3013 ctx.
subnet_ = subnet->getNextSubnet(subnet, ctx.
query_->getClasses());
3026 return (discoverLease4(ctx));
3035 .arg(ctx.
query_->getLabel())
3053 std::map<SubnetID, ConstHostPtr> host_map;
3055 subnet->getSharedNetwork(network);
3060 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3073 const bool use_single_query = network &&
3076 if (use_single_query) {
3081 &id_pair->second[0],
3082 id_pair->second.size());
3086 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
3087 if ((*host)->getIPv4SubnetID() > 0) {
3088 host_map[(*host)->getIPv4SubnetID()] = *host;
3099 if (subnet->clientSupported(ctx.
query_->getClasses()) &&
3104 if (use_single_query) {
3105 if (host_map.count(subnet->getID()) > 0) {
3106 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
3115 id_pair.second.size());
3118 ctx.
hosts_[subnet->getID()] = host;
3128 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3138 &id_pair.second[0], id_pair.second.size());
3156 findClientLease(ctx, client_lease);
3166 if (hasAddressReservation(ctx)) {
3169 ALLOC_ENGINE_V4_DISCOVER_HR)
3170 .arg(ctx.
query_->getLabel())
3171 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
3177 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
3184 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
3188 .arg(ctx.
query_->getLabel())
3189 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3195 new_lease = renewLease4(client_lease, ctx);
3208 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
3209 !addressReserved(client_lease->addr_, ctx)) {
3212 ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE)
3213 .arg(ctx.
query_->getLabel());
3215 new_lease = renewLease4(client_lease, ctx);
3230 ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE)
3232 .arg(ctx.
query_->getLabel());
3244 ALLOC_ENGINE_V4_OFFER_NEW_LEASE)
3245 .arg(ctx.
query_->getLabel());
3247 new_lease = allocateUnreservedLease4(ctx);
3267 findClientLease(ctx, client_lease);
3285 ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED)
3286 .arg(ctx.
query_->getLabel())
3292 }
else if (hasAddressReservation(ctx)) {
3300 ALLOC_ENGINE_V4_REQUEST_USE_HR)
3301 .arg(ctx.
query_->getLabel())
3313 if (existing && !existing->expired() &&
3314 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
3318 ALLOC_ENGINE_V4_REQUEST_IN_USE)
3319 .arg(ctx.
query_->getLabel())
3329 if (hasAddressReservation(ctx) &&
3337 if (!existing || existing->expired()) {
3340 ALLOC_ENGINE_V4_REQUEST_INVALID)
3341 .arg(ctx.
query_->getLabel())
3342 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3352 if ((!hasAddressReservation(ctx) ||
3357 ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL)
3358 .arg(ctx.
query_->getLabel())
3376 (hasAddressReservation(ctx) ||
3377 inAllowedPool(ctx, client_lease->addr_))) {
3380 ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE)
3381 .arg(ctx.
query_->getLabel())
3384 return (renewLease4(client_lease, ctx));
3397 ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED)
3398 .arg(ctx.
query_->getLabel())
3413 ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS)
3414 .arg(ctx.
query_->getLabel());
3419 new_lease = allocateUnreservedLease4(ctx);
3425 if (new_lease && client_lease) {
3429 ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE)
3430 .arg(ctx.
query_->getLabel())
3431 .arg(client_lease->addr_.toText());
3436 StatsMgr::instance().addValue(
3437 StatsMgr::generateName(
"subnet", client_lease->subnet_id_,
"assigned-addresses"),
3438 static_cast<int64_t
>(-1));
3447 AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
3450 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
3453 isc_throw(BadValue,
"Can't create a lease without a subnet");
3456 time_t now = time(NULL);
3459 std::vector<uint8_t> local_copy;
3460 if (ctx.clientid_ && ctx.subnet_->getMatchClientId()) {
3461 local_copy = ctx.clientid_->getDuid();
3463 const uint8_t* local_copy0 = local_copy.empty() ? 0 : &local_copy[0];
3465 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, local_copy0, local_copy.size(),
3466 ctx.subnet_->getValid(), ctx.subnet_->getT1(),
3467 ctx.subnet_->getT2(),
3468 now, ctx.subnet_->getID()));
3471 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
3472 lease->fqdn_rev_ = ctx.rev_dns_update_;
3473 lease->hostname_ = ctx.hostname_;
3476 if (ctx.callout_handle_ &&
3477 HooksManager::getHooksManager().calloutsPresent(hook_index_lease4_select_)) {
3490 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
3496 Subnet4Ptr subnet4 = boost::dynamic_pointer_cast<Subnet4>(ctx.subnet_);
3497 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
3500 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
3503 ctx.callout_handle_->setArgument(
"lease4", lease);
3506 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.callout_handle_);
3508 callout_status = ctx.callout_handle_->getStatus();
3513 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
3520 ctx.callout_handle_->getArgument(
"lease4", lease);
3523 if (!ctx.fake_allocation_) {
3529 StatsMgr::instance().addValue(
3530 StatsMgr::generateName(
"subnet", ctx.subnet_->getID(),
"assigned-addresses"),
3531 static_cast<int64_t
>(1));
3556 AllocEngine::renewLease4(
const Lease4Ptr& lease,
3559 isc_throw(BadValue,
"null lease specified for renewLease4");
3566 Lease4 old_values = *lease;
3570 updateLease4Information(lease, ctx);
3586 if (HooksManager::getHooksManager().
3587 calloutsPresent(
Hooks.hook_index_lease4_renew_)) {
3611 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
3619 HooksManager::callCallouts(
Hooks.hook_index_lease4_renew_,
3625 if (ctx.
callout_handle_->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3628 DHCPSRV_HOOK_LEASE4_RENEW_SKIP);
3640 StatsMgr::instance().addValue(
3641 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
"assigned-addresses"),
3642 static_cast<int64_t
>(1));
3648 *lease = old_values;
3655 AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
3659 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
3663 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
3674 updateLease4Information(expired, ctx);
3677 ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA)
3678 .arg(ctx.
query_->getLabel())
3679 .arg(expired->toText());
3683 .calloutsPresent(hook_index_lease4_select_)) {
3713 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.
callout_handle_);
3720 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
3722 DHCPSRV_HOOK_LEASE4_SELECT_SKIP);
3738 StatsMgr::instance().addValue(
3739 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
"assigned-addresses"),
3740 static_cast<int64_t
>(1));
3752 AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate, ClientContext4& ctx,
3754 ctx.conflicting_lease_.reset();
3758 if (exist_lease->expired()) {
3760 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
3766 ctx.conflicting_lease_ = exist_lease;
3770 return (createLease4(ctx, candidate, callout_status));
3776 AllocEngine::allocateUnreservedLease4(ClientContext4& ctx) {
3791 ctx.subnet_->getSharedNetwork(network);
3798 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
3803 uint64_t total_attempts = 0;
3807 if (subnet->getMatchClientId()) {
3808 client_id = ctx.clientid_;
3811 uint64_t possible_attempts =
3813 ctx.query_->getClasses());
3814 uint64_t max_attempts = (attempts_ > 0 ? attempts_ : possible_attempts);
3816 if (possible_attempts == 0) {
3822 for (uint64_t i = 0; i < max_attempts; ++i) {
3823 IOAddress candidate = allocator->pickAddress(subnet,
3824 ctx.query_->getClasses(),
3826 ctx.requested_address_);
3828 if (!addressReserved(candidate, ctx)) {
3833 new_lease = allocateOrReuseLease4(candidate, ctx, callout_status);
3837 }
else if (ctx.callout_handle_ &&
3838 (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
3849 subnet = subnet->getNextSubnet(original_subnet, ctx.query_->getClasses());
3852 ctx.subnet_ = subnet;
3859 .arg(ctx.query_->getLabel())
3860 .arg(total_attempts);
3866 AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
3868 lease->subnet_id_ = ctx.
subnet_->getID();
3871 lease->cltt_ = time(NULL);
3872 lease->t1_ = ctx.
subnet_->getT1();
3873 lease->t2_ = ctx.
subnet_->getT2();
3874 lease->valid_lft_ = ctx.
subnet_->getValid();
3881 AllocEngine::conditionalExtendLifetime(
Lease& lease)
const {
3882 lease.
cltt_ = time(NULL);