36#include <boost/foreach.hpp>
37#include <boost/make_shared.hpp>
54namespace ph = std::placeholders;
59struct AllocEngineHooks {
60 int hook_index_lease4_select_;
61 int hook_index_lease4_renew_;
62 int hook_index_lease4_expire_;
63 int hook_index_lease4_recover_;
64 int hook_index_lease6_select_;
65 int hook_index_lease6_renew_;
66 int hook_index_lease6_rebind_;
67 int hook_index_lease6_expire_;
68 int hook_index_lease6_recover_;
88AllocEngineHooks
Hooks;
96 : attempts_(attempts), incomplete_v4_reclamations_(0),
97 incomplete_v6_reclamations_(0) {
100 hook_index_lease4_select_ =
Hooks.hook_index_lease4_select_;
101 hook_index_lease6_select_ =
Hooks.hook_index_lease6_select_;
128 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
133 reserved.push_back(host);
144 reserved.insert(reserved.end(), hosts.begin(), hosts.end());
163 const IOAddress& address,
bool check_subnet) {
167 auto const& classes = ctx.
query_->getClasses();
169 while (current_subnet) {
170 if (current_subnet->clientSupported(classes)) {
172 if (current_subnet->inPool(lease_type, address)) {
176 if (current_subnet->inPool(lease_type, address, classes)) {
182 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
209 const std::string& hostname,
210 const bool fake_allocation,
218 ias_(), ddns_params_() {
234 const uint8_t prefix_len,
235 const uint32_t preferred,
236 const uint32_t valid) {
246 addHint(iaaddr->getAddress(), 128,
247 iaaddr->getPreferred(), iaaddr->getValid());
256 addHint(iaprefix->getAddress(), iaprefix->getLength(),
257 iaprefix->getPreferred(), iaprefix->getValid());
263 const uint8_t prefix_len) {
270 const uint8_t prefix_len)
const {
278 const uint8_t prefix_len) {
286 return (
static_cast<bool>
293 if (subnet && subnet->getReservationsInSubnet()) {
294 auto host =
hosts_.find(subnet->getID());
295 if (host !=
hosts_.cend()) {
296 return (host->second);
306 if (subnet &&
subnet_->getReservationsGlobal()) {
307 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
308 if (host !=
hosts_.cend()) {
309 return (host->second);
319 return (ghost && ghost->hasReservation(resv));
325 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
326 return (ddns_params_);
332 return (ddns_params_);
351 !subnet->getReservationsInSubnet()) {
357 subnet->getReservationsGlobal()) {
360 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
363 if (!subnet->getReservationsInSubnet()) {
369 std::map<SubnetID, ConstHostPtr> host_map;
371 subnet->getSharedNetwork(network);
380 const bool use_single_query = network &&
384 if (use_single_query) {
388 id_pair.second.size());
392 for (
auto const& host : hosts) {
393 if (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL) {
394 host_map[host->getIPv6SubnetID()] = host;
400 auto const& classes = ctx.
query_->getClasses();
407 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
410 if (use_single_query) {
411 if (host_map.count(subnet->getID()) > 0) {
412 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
420 id_pair.second.size());
423 ctx.
hosts_[subnet->getID()] = host;
433 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
439 for (
auto const& host : ctx.
hosts_) {
440 host.second->encapsulateOptions();
450 &id_pair.second[0], id_pair.second.size());
484 for (
auto const& l : all_leases) {
486 ((l)->subnet_id_ == subnet->getID())) {
491 subnet = subnet->getNextSubnet(ctx.
subnet_);
511 if (leases.empty() && !ctx.
hosts_.empty()) {
515 .arg(ctx.
query_->getLabel());
520 allocateReservedLeases6(ctx, leases);
522 leases = updateLeaseData(ctx, leases);
537 }
else if (!leases.empty() && ctx.
hosts_.empty()) {
541 .arg(ctx.
query_->getLabel());
545 removeNonmatchingReservedLeases6(ctx, leases);
547 leases = updateLeaseData(ctx, leases);
556 }
else if (!leases.empty() && !ctx.
hosts_.empty()) {
560 .arg(ctx.
query_->getLabel());
564 allocateReservedLeases6(ctx, leases);
576 removeNonmatchingReservedLeases6(ctx, leases);
585 removeNonreservedLeases6(ctx, leases);
590 leases = updateLeaseData(ctx, leases);
603 if (leases.empty()) {
617 .arg(ctx.
query_->getLabel());
619 leases = allocateUnreservedLeases6(ctx);
622 if (!leases.empty()) {
626 for (
auto const& lease : leases) {
640 .arg(ctx.
query_->getLabel())
653 uint8_t hint_prefix_length = 128;
654 if (!ctx.currentIA().hints_.empty()) {
656 hint = ctx.currentIA().hints_[0].getAddress();
657 hint_prefix_length = ctx.currentIA().hints_[0].getPrefixLength();
666 uint64_t total_attempts = 0;
670 uint64_t subnets_with_unavail_leases = 0;
673 uint64_t subnets_with_unavail_pools = 0;
683 bool search_hint_lease =
true;
690 if (hint_prefix_length == 128) {
691 hint_prefix_length = 0;
693 if (!hint_prefix_length) {
701 Lease6Ptr lease = allocateBestMatch(ctx, hint_lease, search_hint_lease,
702 hint, hint_prefix_length, subnet,
703 network, total_attempts,
704 subnets_with_unavail_leases,
705 subnets_with_unavail_pools,
706 callout_status, prefix_length_match);
714 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
715 hint_prefix_length, subnet, network,
716 total_attempts, subnets_with_unavail_leases,
717 subnets_with_unavail_pools, callout_status,
718 prefix_length_match);
727 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
728 hint_prefix_length, subnet, network,
729 total_attempts, subnets_with_unavail_leases,
730 subnets_with_unavail_pools, callout_status,
731 prefix_length_match);
735 leases.push_back(lease);
739 auto const& classes = ctx.query_->getClasses();
745 .arg(ctx.query_->getLabel())
746 .arg(network->getName())
747 .arg(subnets_with_unavail_leases)
748 .arg(subnets_with_unavail_pools);
750 static_cast<int64_t
>(1));
753 "v6-allocation-fail-shared-network"),
754 static_cast<int64_t
>(1));
758 std::string shared_network = ctx.subnet_->getSharedNetworkName();
759 if (shared_network.empty()) {
760 shared_network =
"(none)";
763 .arg(ctx.query_->getLabel())
764 .arg(ctx.subnet_->toText())
765 .arg(ctx.subnet_->getID())
766 .arg(shared_network);
768 static_cast<int64_t
>(1));
771 "v6-allocation-fail-subnet"),
772 static_cast<int64_t
>(1));
774 if (total_attempts == 0) {
780 .arg(ctx.query_->getLabel());
782 static_cast<int64_t
>(1));
785 "v6-allocation-fail-no-pools"),
786 static_cast<int64_t
>(1));
793 .arg(ctx.query_->getLabel())
794 .arg(total_attempts);
796 static_cast<int64_t
>(1));
799 "v6-allocation-fail"),
800 static_cast<int64_t
>(1));
803 if (!classes.empty()) {
805 .arg(ctx.query_->getLabel())
806 .arg(classes.toText());
808 static_cast<int64_t
>(1));
811 "v6-allocation-fail-classes"),
812 static_cast<int64_t
>(1));
822 bool& search_hint_lease,
823 const isc::asiolink::IOAddress& hint,
824 uint8_t hint_prefix_length,
827 uint64_t& total_attempts,
828 uint64_t& subnets_with_unavail_leases,
829 uint64_t& subnets_with_unavail_pools,
832 auto const& classes = ctx.query_->getClasses();
837 if (!search_hint_lease) {
838 usable_hint_lease = hint_lease;
840 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
841 if (!subnet->clientSupported(classes)) {
845 ctx.subnet_ = subnet;
849 pool = boost::dynamic_pointer_cast<Pool6>
850 (subnet->getPool(ctx.currentIA().type_, classes, hint));
853 if (!pool || !pool->clientSupported(classes)) {
859 hint_prefix_length)) {
863 bool in_subnet = subnet->getReservationsInSubnet();
866 if (search_hint_lease) {
867 search_hint_lease =
false;
869 usable_hint_lease = hint_lease;
871 if (!usable_hint_lease) {
883 (!subnet->getReservationsOutOfPool() ||
884 !subnet->inPool(ctx.currentIA().type_, hint))) {
885 hosts = getIPv6Resrv(subnet->getID(), hint);
895 Lease6Ptr new_lease = createLease6(ctx, hint, pool->getLength(), callout_status);
908 .arg(ctx.query_->getLabel())
912 }
else if (usable_hint_lease->expired() &&
922 (!subnet->getReservationsOutOfPool() ||
923 !subnet->inPool(ctx.currentIA().type_, hint))) {
924 hosts = getIPv6Resrv(subnet->getID(), hint);
932 Lease6Ptr old_lease(
new Lease6(*usable_hint_lease));
933 ctx.currentIA().old_leases_.push_back(old_lease);
936 Lease6Ptr lease = reuseExpiredLease(usable_hint_lease, ctx,
946 .arg(ctx.query_->getLabel())
958 if (!check_reservation_first) {
972 original_subnet->getSharedNetwork(network);
979 original_subnet = network->getPreferredSubnet(original_subnet, ctx.currentIA().type_);
982 ctx.subnet_ = subnet = original_subnet;
984 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
985 if (!subnet->clientSupported(classes)) {
996 subnet->getPoolCapacity(ctx.currentIA().type_,
1007 (attempts_ == 0 || possible_attempts < attempts_) ?
1011 if (max_attempts > 0) {
1014 ++subnets_with_unavail_leases;
1018 ++subnets_with_unavail_pools;
1022 bool in_subnet = subnet->getReservationsInSubnet();
1023 bool out_of_pool = subnet->getReservationsOutOfPool();
1028 if (ctx.callout_handle_) {
1032 for (uint64_t i = 0; i < max_attempts; ++i) {
1035 auto allocator = subnet->getAllocator(ctx.currentIA().type_);
1040 uint8_t prefix_len = 128;
1042 candidate = allocator->pickPrefix(classes, pool, ctx.duid_,
1043 prefix_length_match, hint,
1044 hint_prefix_length);
1046 prefix_len = pool->getLength();
1049 candidate = allocator->pickAddress(classes, ctx.duid_, hint);
1058 if (check_reservation_first && in_subnet && !out_of_pool) {
1059 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1060 if (!hosts.empty()) {
1068 ResourceHandler resource_handler;
1070 !resource_handler.
tryLock(ctx.currentIA().type_, candidate)) {
1083 if (!check_reservation_first && in_subnet && !out_of_pool) {
1084 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1085 if (!hosts.empty()) {
1094 ctx.subnet_ = subnet;
1095 Lease6Ptr new_lease = createLease6(ctx, candidate, prefix_len, callout_status);
1099 ctx.currentIA().old_leases_.clear();
1103 }
else if (ctx.callout_handle_ &&
1112 }
else if (existing->expired() &&
1115 if (!check_reservation_first && in_subnet && !out_of_pool) {
1116 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1117 if (!hosts.empty()) {
1125 Lease6Ptr old_lease(
new Lease6(*existing));
1126 ctx.currentIA().old_leases_.push_back(old_lease);
1128 ctx.subnet_ = subnet;
1129 existing = reuseExpiredLease(existing, ctx, prefix_len,
1144 if (ctx.hosts_.empty()) {
1147 .arg(ctx.query_->getLabel());
1158 for (
auto const& lease : existing_leases) {
1159 if ((lease->valid_lft_ != 0)) {
1160 if ((ctx.hosts_.count(lease->subnet_id_) > 0) &&
1161 ctx.hosts_[lease->subnet_id_]->hasReservation(
makeIPv6Resrv(*lease))) {
1166 .arg(ctx.query_->getLabel())
1167 .arg(lease->typeToText(lease->type_))
1168 .arg(lease->addr_.toText());
1174 if (!ctx.host_subnet_) {
1176 ctx.subnet_->getSharedNetwork(network);
1181 ctx.host_subnet_ = network->getSubnet(lease->subnet_id_);
1189 if (host && !host->getHostname().empty()) {
1196 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1197 static_cast<bool>(fqdn));
1211 auto const& classes = ctx.query_->getClasses();
1213 subnet = subnet->getNextSubnet(ctx.subnet_)) {
1215 SubnetID subnet_id = subnet->getID();
1218 if (!subnet->clientSupported(classes) || ctx.hosts_.count(subnet_id) == 0) {
1224 bool in_subnet = subnet->getReservationsInSubnet();
1228 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1230 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1231 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1235 if (ctx.isAllocated(addr, prefix_len)) {
1244 (subnet->getReservationsOutOfPool() &&
1245 subnet->inPool(ctx.currentIA().type_, addr))) {
1257 ctx.subnet_ = subnet;
1259 if (!ctx.host_subnet_) {
1260 ctx.host_subnet_ = subnet;
1261 if (!host->getHostname().empty()) {
1275 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1276 static_cast<bool>(fqdn));
1282 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1285 existing_leases.push_back(lease);
1290 .arg(ctx.query_->getLabel());
1294 .arg(
static_cast<int>(prefix_len))
1295 .arg(ctx.query_->getLabel());
1313 allocateGlobalReservedLeases6(ctx, existing_leases);
1328 for (
auto const& lease : existing_leases) {
1329 if ((lease->valid_lft_ != 0) &&
1335 .arg(ctx.query_->getLabel())
1336 .arg(lease->typeToText(lease->type_))
1337 .arg(lease->addr_.toText());
1343 if (!ghost->getHostname().empty()) {
1350 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1351 static_cast<bool>(fqdn));
1366 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1367 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1369 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1370 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1374 if (ctx.isAllocated(addr, prefix_len)) {
1386 bool valid_subnet =
false;
1387 auto subnet = ctx.subnet_;
1389 if (subnet->inRange(addr)) {
1390 valid_subnet =
true;
1394 subnet = subnet->getNextSubnet(ctx.subnet_);
1397 if (!valid_subnet) {
1400 .arg(ctx.query_->getLabel())
1406 ctx.subnet_ = subnet;
1409 if (!ghost->getHostname().empty()) {
1423 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1424 static_cast<bool>(fqdn));
1429 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1432 existing_leases.push_back(lease);
1437 .arg(ctx.query_->getLabel());
1441 .arg(
static_cast<int>(prefix_len))
1442 .arg(ctx.query_->getLabel());
1460AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1463 if (existing_leases.empty() || !ctx.subnet_) {
1468 if (!ctx.subnet_->getReservationsInSubnet() &&
1469 !ctx.subnet_->getReservationsGlobal()) {
1470 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1479 for (
auto const& candidate :
copy) {
1483 if ((ctx.hasGlobalReservation(resv)) ||
1484 ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
1485 (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1494 auto hosts = getIPv6Resrv(ctx.subnet_->getID(), candidate->addr_);
1499 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1500 candidate->addr_,
false)) {
1504 if (!hosts.empty()) {
1507 if (hosts.size() == 1) {
1510 .arg(ctx.query_->getLabel())
1511 .arg(candidate->addr_.
toText())
1512 .arg(ctx.duid_->toText())
1513 .arg(hosts.front()->getIdentifierAsText());
1516 .arg(ctx.query_->getLabel())
1517 .arg(candidate->addr_.
toText())
1518 .arg(
static_cast<int>(candidate->prefixlen_))
1519 .arg(ctx.duid_->toText())
1520 .arg(hosts.front()->getIdentifierAsText());
1525 .arg(ctx.query_->getLabel())
1526 .arg(candidate->addr_.
toText())
1527 .arg(ctx.duid_->toText())
1531 .arg(ctx.query_->getLabel())
1532 .arg(candidate->addr_.
toText())
1533 .arg(
static_cast<int>(candidate->prefixlen_))
1534 .arg(ctx.duid_->toText())
1553 "assigned-nas" :
"assigned-pds",
1554 static_cast<int64_t
>(-1));
1559 "assigned-nas" :
"assigned-pds"),
1560 static_cast<int64_t
>(-1));
1564 auto const& pool = subnet->getPool(ctx.currentIA().type_, candidate->addr_,
false);
1569 "pool" :
"pd-pool", pool->getID(),
1571 "assigned-nas" :
"assigned-pds")),
1572 static_cast<int64_t
>(-1));
1582 ctx.currentIA().old_leases_.push_back(candidate);
1585 removeLeases(existing_leases, candidate->addr_);
1590AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1597 for (
auto const& candidate :
copy) {
1601 if (inAllowedPool(ctx, candidate->type_,
1602 candidate->addr_,
false)) {
1618 "assigned-nas" :
"assigned-pds",
1619 static_cast<int64_t
>(-1));
1624 "assigned-nas" :
"assigned-pds"),
1625 static_cast<int64_t
>(-1));
1629 auto const& pool = subnet->getPool(candidate->type_, candidate->addr_,
false);
1634 "pool" :
"pd-pool", pool->getID(),
1636 "assigned-nas" :
"assigned-pds")),
1637 static_cast<int64_t
>(-1));
1642 ctx.currentIA().old_leases_.push_back(candidate);
1645 removeLeases(existing_leases, candidate->addr_);
1650AllocEngine::removeLeases(
Lease6Collection& container,
const asiolink::IOAddress& addr) {
1652 bool removed =
false;
1653 for (Lease6Collection::iterator lease = container.begin();
1654 lease != container.end(); ++lease) {
1655 if ((*lease)->addr_ == addr) {
1662 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1673 int total = existing_leases.size();
1680 for (Lease6Collection::iterator lease = existing_leases.begin();
1681 lease != existing_leases.end(); ++lease) {
1685 if (ctx.hasGlobalReservation(resv) ||
1686 ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
1687 (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1707 "assigned-nas" :
"assigned-pds",
1708 static_cast<int64_t
>(-1));
1713 "assigned-nas" :
"assigned-pds"),
1714 static_cast<int64_t
>(-1));
1718 auto const& pool = subnet->getPool(ctx.currentIA().type_, (*lease)->addr_,
false);
1723 "pool" :
"pd-pool", pool->getID(),
1725 "assigned-nas" :
"assigned-pds")),
1726 static_cast<int64_t
>(-1));
1733 ctx.currentIA().old_leases_.push_back(*lease);
1748 existing_leases.erase(std::remove(existing_leases.begin(),
1749 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1754useMinLifetimes6(AllocEngine::ClientContext6& ctx,
const IOAddress& addr,
1755 uint8_t prefix_len) {
1756 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
1757 if (!threshold.unspecified() && (threshold < 1.0)) {
1759 getOccupancyRate(addr, prefix_len, ctx.
query_->getClasses());
1760 if (occupancy >= threshold) {
1773 if (!expired->expired()) {
1774 isc_throw(BadValue,
"Attempt to recycle lease that is still valid");
1778 isc_throw(BadValue,
"Attempt to recycle registered address");
1785 if (!ctx.fake_allocation_) {
1789 reclaimExpiredLease(expired, ctx.callout_handle_);
1793 expired->iaid_ = ctx.currentIA().iaid_;
1794 expired->duid_ = ctx.duid_;
1795 expired->hwaddr_ = ctx.hwaddr_;
1798 expired->preferred_lft_ = 0;
1799 expired->valid_lft_ = 0;
1801 useMinLifetimes6(ctx, expired->addr_, prefix_len)) {
1804 getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
1806 expired->reuseable_valid_lft_ = 0;
1808 expired->cltt_ = time(0);
1809 expired->subnet_id_ = ctx.subnet_->getID();
1810 expired->hostname_ = ctx.hostname_;
1811 expired->fqdn_fwd_ = ctx.fwd_dns_update_;
1812 expired->fqdn_rev_ = ctx.rev_dns_update_;
1813 expired->prefixlen_ = prefix_len;
1818 .arg(ctx.query_->getLabel())
1819 .arg(expired->toText());
1822 if (ctx.callout_handle_ &&
1829 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
1832 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
1837 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1840 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1843 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1846 ctx.callout_handle_->setArgument(
"lease6", expired);
1851 callout_status = ctx.callout_handle_->getStatus();
1868 ctx.callout_handle_->getArgument(
"lease6", expired);
1871 if (!ctx.fake_allocation_) {
1875 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_,
false);
1877 expired->pool_id_ = pool->getID();
1885 if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
1889 "assigned-nas" :
"assigned-pds"),
1890 static_cast<int64_t
>(1));
1895 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
1896 static_cast<int64_t
>(1));
1902 "pool" :
"pd-pool", pool->getID(),
1904 "assigned-nas" :
"assigned-pds")),
1905 static_cast<int64_t
>(1));
1910 "pool" :
"pd-pool", pool->getID(),
1912 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
1913 static_cast<int64_t
>(1));
1917 "assigned-nas" :
"assigned-pds",
1918 static_cast<int64_t
>(1));
1921 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
1922 static_cast<int64_t
>(1));
1935void sanitizeLifetimes6(AllocEngine::ClientContext6& ctx,
1936 uint32_t& preferred, uint32_t& valid) {
1938 if (!preferred || preferred > valid) {
1939 preferred = ((valid * 5)/8);
1942 .arg(ctx.
query_->getLabel())
1955 if (!classes.
empty()) {
1962 for (
auto const& name : classes) {
1965 (cl && (!cl->getPreferred().unspecified()))) {
1966 candidate_preferred = cl->getPreferred();
1971 (cl && (!cl->getValid().unspecified()))) {
1972 candidate_valid = cl->getValid();
1975 if (have_both == 2) {
1982 if (!candidate_preferred) {
1983 candidate_preferred = ctx.
subnet_->getPreferred();
1987 if (!candidate_valid) {
1988 candidate_valid = ctx.
subnet_->getValid();
1992 preferred = candidate_preferred;
1993 valid = candidate_valid;
2007 sanitizeLifetimes6(ctx, preferred, valid);
2018 if (!classes.
empty()) {
2025 for (
auto const& name : classes) {
2028 (cl && (!cl->getPreferred().unspecified()))) {
2029 candidate_preferred = cl->getPreferred();
2034 (cl && (!cl->getValid().unspecified()))) {
2035 candidate_valid = cl->getValid();
2038 if (have_both == 2) {
2045 if (!candidate_preferred) {
2046 candidate_preferred = ctx.
subnet_->getPreferred();
2050 if (!candidate_valid) {
2051 candidate_valid = ctx.
subnet_->getValid();
2055 uint32_t remain_preferred(preferred);
2056 uint32_t remain_valid(valid);
2059 preferred = candidate_preferred.
getMin();
2060 valid = candidate_valid.
getMin();
2063 if (remain_preferred > preferred) {
2064 preferred = remain_preferred;
2066 if (remain_valid > valid) {
2067 valid = remain_valid;
2070 sanitizeLifetimes6(ctx, preferred, valid);
2082 uint32_t preferred = 0;
2085 useMinLifetimes6(ctx, addr, prefix_len)) {
2091 Lease6Ptr lease(
new Lease6(ctx.currentIA().type_, addr, ctx.duid_,
2092 ctx.currentIA().iaid_, preferred,
2093 valid, ctx.subnet_->getID(),
2094 ctx.hwaddr_, prefix_len));
2096 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2097 lease->fqdn_rev_ = ctx.rev_dns_update_;
2098 lease->hostname_ = ctx.hostname_;
2101 if (ctx.callout_handle_ &&
2108 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
2111 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2116 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
2119 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
2122 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
2125 ctx.callout_handle_->setArgument(
"lease6", lease);
2130 callout_status = ctx.callout_handle_->getStatus();
2142 ctx.callout_handle_->getArgument(
"lease6", lease);
2145 if (!ctx.fake_allocation_) {
2149 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2151 lease->pool_id_ = pool->getID();
2160 if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
2164 "assigned-nas" :
"assigned-pds"),
2165 static_cast<int64_t
>(1));
2170 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2171 static_cast<int64_t
>(1));
2177 "pool" :
"pd-pool", pool->getID(),
2179 "assigned-nas" :
"assigned-pds")),
2180 static_cast<int64_t
>(1));
2185 "pool" :
"pd-pool", pool->getID(),
2187 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2188 static_cast<int64_t
>(1));
2192 "assigned-nas" :
"assigned-pds",
2193 static_cast<int64_t
>(1));
2196 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2197 static_cast<int64_t
>(1));
2201 ctx.currentIA().addNewResource(addr, prefix_len);
2228 time_t now = time(0);
2230 if (lease->cltt_ > now) {
2233 uint32_t age = now - lease->cltt_;
2235 if (age >= lease->valid_lft_) {
2238 valid = lease->valid_lft_ - age;
2239 if (age >= lease->preferred_lft_) {
2242 preferred = lease->preferred_lft_ - age;
2265 for (
auto const& l : leases_subnet) {
2267 leases.push_back(l);
2270 subnet = subnet->getNextSubnet(ctx.
subnet_);
2273 if (!leases.empty()) {
2276 .arg(ctx.
query_->getLabel());
2280 removeNonmatchingReservedLeases6(ctx, leases);
2283 if (!ctx.
hosts_.empty()) {
2287 .arg(ctx.
query_->getLabel());
2290 allocateReservedLeases6(ctx, leases);
2296 removeNonreservedLeases6(ctx, leases);
2303 if (leases.empty()) {
2307 .arg(ctx.
query_->getLabel());
2309 leases = allocateUnreservedLeases6(ctx);
2313 for (
auto const& l : leases) {
2321 .arg(ctx.
query_->getLabel())
2322 .arg(l->typeToText(l->type_))
2324 extendLease6(ctx, l);
2327 if (!leases.empty()) {
2331 for (
auto const& lease : leases) {
2346 .arg(ctx.
query_->getLabel())
2356 if (!lease || !ctx.subnet_) {
2362 if (ctx.subnet_->getID() != lease->subnet_id_) {
2364 ctx.subnet_->getSharedNetwork(network);
2367 network->getSubnet(
SubnetID(lease->subnet_id_));
2371 ctx.subnet_ = subnet;
2379 (((lease->type_ !=
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
2380 !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
2395 "assigned-nas" :
"assigned-pds",
static_cast<int64_t
>(-1));
2400 "assigned-nas" :
"assigned-pds"),
2401 static_cast<int64_t
>(-1));
2403 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2408 "pool" :
"pd-pool", pool->getID(),
2410 "assigned-nas" :
"assigned-pds")),
2411 static_cast<int64_t
>(-1));
2415 ctx.currentIA().old_leases_.push_back(lease);
2422 .arg(ctx.query_->getLabel())
2423 .arg(lease->toText());
2428 bool changed =
false;
2431 uint32_t current_preferred_lft = lease->preferred_lft_;
2433 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2434 uint32_t remain_preferred_lft(0);
2435 uint32_t remain_valid_lft(0);
2436 getRemaining(lease, remain_preferred_lft, remain_valid_lft);
2437 lease->preferred_lft_ = remain_preferred_lft;
2438 lease->valid_lft_ = remain_valid_lft;
2441 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2445 if ((lease->preferred_lft_ != current_preferred_lft) ||
2446 (lease->valid_lft_ != lease->current_valid_lft_)) {
2450 lease->cltt_ = time(NULL);
2451 if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
2452 (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
2453 (lease->hostname_ != ctx.hostname_)) {
2455 lease->hostname_ = ctx.hostname_;
2456 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2457 lease->fqdn_rev_ = ctx.rev_dns_update_;
2459 if ((!ctx.hwaddr_ && lease->hwaddr_) ||
2461 (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
2463 lease->hwaddr_ = ctx.hwaddr_;
2471 .arg(ctx.query_->getLabel())
2472 .arg(lease->toText());
2476 int hook_point = ctx.query_->getType() ==
DHCPV6_RENEW ?
2477 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2485 ScopedCalloutHandleState callout_handle_state(callout_handle);
2488 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2491 callout_handle->setArgument(
"query6", ctx.query_);
2494 callout_handle->setArgument(
"lease6", lease);
2498 callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
2500 callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
2513 .arg(ctx.query_->getName());
2520 bool update_stats =
false;
2524 if (old_data->expired()) {
2525 reclaimExpiredLease(old_data, ctx.callout_handle_);
2529 if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
2530 update_stats =
true;
2543 setLeaseReusable(lease, current_preferred_lft, ctx);
2548 if (lease->reuseable_valid_lft_ == 0) {
2549 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2551 lease->pool_id_ = pool->getID();
2557 old_data->reuseable_valid_lft_ = lease->reuseable_valid_lft_;
2564 "assigned-nas" :
"assigned-pds"),
2565 static_cast<int64_t
>(1));
2570 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2571 static_cast<int64_t
>(1));
2573 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2578 "pool" :
"pd-pool", pool->getID(),
2580 "assigned-nas" :
"assigned-pds")),
2581 static_cast<int64_t
>(1));
2586 "pool" :
"pd-pool", pool->getID(),
2588 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2589 static_cast<int64_t
>(1));
2593 "assigned-nas" :
"assigned-pds",
2594 static_cast<int64_t
>(1));
2598 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2599 static_cast<int64_t
>(1));
2612 ctx.currentIA().changed_leases_.push_back(old_data);
2618 for (
auto const& lease_it : leases) {
2620 if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
2622 updated_leases.push_back(lease);
2626 lease->reuseable_valid_lft_ = 0;
2627 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2628 lease->fqdn_rev_ = ctx.rev_dns_update_;
2629 lease->hostname_ = ctx.hostname_;
2630 uint32_t current_preferred_lft = lease->preferred_lft_;
2631 if (lease->valid_lft_ == 0) {
2633 lease->preferred_lft_ = 0;
2635 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2638 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2641 if (!ctx.fake_allocation_) {
2642 bool update_stats =
false;
2650 if (inAllowedPool(ctx, ctx.currentIA().type_,
2651 lease->addr_,
true)) {
2652 update_stats =
true;
2657 !(lease->hasIdenticalFqdn(*lease_it)));
2659 lease->cltt_ = time(NULL);
2660 if (!fqdn_changed) {
2661 setLeaseReusable(lease, current_preferred_lft, ctx);
2664 if (lease->reuseable_valid_lft_ == 0) {
2665 ctx.currentIA().changed_leases_.push_back(lease_it);
2669 ctx.currentIA().reused_leases_.push_back(lease_it);
2676 "assigned-nas" :
"assigned-pds"),
2677 static_cast<int64_t
>(1));
2682 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2683 static_cast<int64_t
>(1));
2685 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2690 "pool" :
"pd-pool", pool->getID(),
2692 "assigned-nas" :
"assigned-pds")),
2693 static_cast<int64_t
>(1));
2698 "pool" :
"pd-pool", pool->getID(),
2700 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2701 static_cast<int64_t
>(1));
2705 "assigned-nas" :
"assigned-pds",
2706 static_cast<int64_t
>(1));
2709 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2710 static_cast<int64_t
>(1));
2714 updated_leases.push_back(lease);
2717 return (updated_leases);
2722 const uint16_t timeout,
2723 const bool remove_lease,
2724 const uint16_t max_unwarned_cycles) {
2733 max_unwarned_cycles);
2734 }
catch (
const std::exception& ex) {
2743 const uint16_t timeout,
2744 const bool remove_lease,
2745 const uint16_t max_unwarned_cycles) {
2755 bool incomplete_reclamation =
false;
2758 if (max_leases > 0) {
2767 if (leases.size() > max_leases) {
2769 incomplete_reclamation =
true;
2782 if (!leases.empty() &&
2787 size_t leases_processed = 0;
2788 for (
auto const& lease : leases) {
2796 reclaimExpiredLease(lease, remove_lease, callout_handle);
2799 reclaimExpiredLease(lease, remove_lease, callout_handle);
2803 }
catch (
const std::exception& ex) {
2805 .arg(lease->addr_.toText())
2816 if (!incomplete_reclamation) {
2817 if (leases_processed < leases.size()) {
2818 incomplete_reclamation =
true;
2835 .arg(leases_processed)
2840 if (incomplete_reclamation) {
2841 ++incomplete_v6_reclamations_;
2844 if ((max_unwarned_cycles > 0) &&
2845 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2847 .arg(max_unwarned_cycles);
2849 incomplete_v6_reclamations_ = 0;
2854 incomplete_v6_reclamations_ = 0;
2867 uint64_t deleted_leases = 0;
2873 }
catch (
const std::exception& ex) {
2880 .arg(deleted_leases);
2885 const uint16_t timeout,
2886 const bool remove_lease,
2887 const uint16_t max_unwarned_cycles) {
2896 max_unwarned_cycles);
2897 }
catch (
const std::exception& ex) {
2906 const uint16_t timeout,
2907 const bool remove_lease,
2908 const uint16_t max_unwarned_cycles) {
2918 bool incomplete_reclamation =
false;
2921 if (max_leases > 0) {
2930 if (leases.size() > max_leases) {
2932 incomplete_reclamation =
true;
2945 if (!leases.empty() &&
2950 size_t leases_processed = 0;
2951 for (
auto const& lease : leases) {
2959 reclaimExpiredLease(lease, remove_lease, callout_handle);
2962 reclaimExpiredLease(lease, remove_lease, callout_handle);
2966 }
catch (
const std::exception& ex) {
2968 .arg(lease->addr_.toText())
2979 if (!incomplete_reclamation) {
2980 if (leases_processed < leases.size()) {
2981 incomplete_reclamation =
true;
2998 .arg(leases_processed)
3003 if (incomplete_reclamation) {
3004 ++incomplete_v4_reclamations_;
3007 if ((max_unwarned_cycles > 0) &&
3008 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
3010 .arg(max_unwarned_cycles);
3012 incomplete_v4_reclamations_ = 0;
3017 incomplete_v4_reclamations_ = 0;
3024template<
typename LeasePtrType>
3026AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
3028 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
3032template<
typename LeasePtrType>
3034AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
3039 if (!lease->stateExpiredReclaimed()) {
3040 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
3045AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
3046 const DbReclaimMode& reclaim_mode,
3052 .arg(lease->addr_.toText())
3053 .arg(
static_cast<int>(lease->prefixlen_));
3059 bool skipped =
false;
3062 if (callout_handle) {
3068 ScopedCalloutHandleState callout_handle_state(callout_handle);
3070 callout_handle->deleteAllArguments();
3071 callout_handle->setArgument(
"lease6", lease);
3072 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3092 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3102 remove_lease = reclaimDeclined(lease);
3104 if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
3105 isc_throw(Unexpected,
"attempt to reuse a registered lease");
3108 remove_lease =
true;
3111 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3115 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
3117 &lease_mgr, ph::_1));
3129 "reclaimed-leases"),
3130 static_cast<int64_t
>(1));
3136 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3142 pool->getID(),
"reclaimed-leases")),
3143 static_cast<int64_t
>(1));
3159 static_cast<int64_t
>(-1));
3163 "assigned-nas" :
"assigned-pds",
3164 static_cast<int64_t
>(-1));
3169 "assigned-nas" :
"assigned-pds"),
3170 static_cast<int64_t
>(-1));
3173 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3178 "pool" :
"pd-pool", pool->getID(),
3180 "assigned-nas" :
"assigned-pds")),
3181 static_cast<int64_t
>(-1));
3188AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
3189 const DbReclaimMode& reclaim_mode,
3195 .arg(lease->addr_.toText());
3201 bool skipped =
false;
3203 if (callout_handle) {
3209 ScopedCalloutHandleState callout_handle_state(callout_handle);
3211 callout_handle->setArgument(
"lease4", lease);
3212 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3230 lease->hostname_.clear();
3231 lease->fqdn_fwd_ =
false;
3232 lease->fqdn_rev_ =
false;
3236 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3246 remove_lease = reclaimDeclined(lease);
3249 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3253 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
3255 &lease_mgr, ph::_1));
3267 "reclaimed-leases"),
3268 static_cast<int64_t
>(1));
3273 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3278 "reclaimed-leases")),
3279 static_cast<int64_t
>(1));
3293 "assigned-addresses"),
3294 static_cast<int64_t
>(-1));
3297 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3302 "assigned-addresses")),
3303 static_cast<int64_t
>(-1));
3314 uint64_t deleted_leases = 0;
3320 }
catch (
const std::exception& ex) {
3327 .arg(deleted_leases);
3331AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3346 callout_handle->setArgument(
"lease4", lease);
3356 .arg(lease->addr_.toText());
3362 .arg(lease->addr_.toText())
3363 .arg(lease->valid_lft_);
3369 "declined-addresses"),
3370 static_cast<int64_t
>(-1));
3373 "reclaimed-declined-addresses"),
3374 static_cast<int64_t
>(1));
3378 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3382 "declined-addresses")),
3383 static_cast<int64_t
>(-1));
3387 "reclaimed-declined-addresses")),
3388 static_cast<int64_t
>(1));
3393 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3395 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3403AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3415 ScopedCalloutHandleState callout_handle_state(callout_handle);
3418 callout_handle->setArgument(
"lease6", lease);
3428 .arg(lease->addr_.toText());
3434 .arg(lease->addr_.toText())
3435 .arg(lease->valid_lft_);
3441 "declined-addresses"),
3442 static_cast<int64_t
>(-1));
3445 "reclaimed-declined-addresses"),
3446 static_cast<int64_t
>(1));
3450 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3454 "declined-addresses")),
3455 static_cast<int64_t
>(-1));
3459 "reclaimed-declined-addresses")),
3460 static_cast<int64_t
>(1));
3465 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3467 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3476 lease->relay_id_.clear();
3477 lease->remote_id_.clear();
3478 if (lease->getContext()) {
3485 if (lease->getContext()) {
3491template<
typename LeasePtrType>
3492void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3493 const bool remove_lease,
3494 const std::function<
void (
const LeasePtrType&)>&
3495 lease_update_fun)
const {
3503 }
else if (lease_update_fun) {
3506 lease->reuseable_valid_lft_ = 0;
3507 lease->hostname_.clear();
3508 lease->fqdn_fwd_ =
false;
3509 lease->fqdn_rev_ =
false;
3512 lease_update_fun(lease);
3521 .arg(lease->addr_.toText());
3527 return(
"<empty subnet>");
3531 subnet->getSharedNetwork(network);
3532 std::ostringstream ss;
3534 ss <<
"shared-network: " << network->getName();
3536 ss <<
"subnet id: " << subnet->getID();
3575 (!ctx.
subnet_->getReservationsOutOfPool() ||
3586 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
3591 hosts.push_back(host);
3605 for (
auto const& host : hosts) {
3609 if (id_pair.first == host->getIdentifierType() &&
3610 id_pair.second == host->getIdentifier()) {
3618 return (!hosts.empty());
3640 if (ctx.
hosts_.empty()) {
3645 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3646 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3647 global_host->second->getIPv4Reservation() :
3656 if (subnet->getReservationsGlobal() &&
3658 (subnet->inRange(global_host_address))) {
3663 if (subnet->getReservationsInSubnet()) {
3664 auto host = ctx.
hosts_.find(subnet->getID());
3669 if (host != ctx.
hosts_.end() && host->second) {
3670 auto reservation = host->second->getIPv4Reservation();
3671 if (!reservation.isV4Zero() &&
3672 (!subnet->getReservationsOutOfPool() ||
3682 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3688 .arg(ctx.
query_->getLabel())
3689 .arg(global_host_address.toText())
3716 auto const& classes = ctx.
query_->getClasses();
3720 bool try_clientid_lookup = (ctx.
clientid_ &&
3724 if (try_clientid_lookup) {
3733 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3738 if (subnet->getMatchClientId()) {
3739 for (
auto const& l : leases_client_id) {
3740 if (l->subnet_id_ == subnet->getID()) {
3753 if (!client_lease && ctx.
hwaddr_) {
3759 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3761 if (subnet->getMatchClientId()) {
3767 for (
auto const& client_lease_it : leases_hw_address) {
3768 Lease4Ptr existing_lease = client_lease_it;
3769 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3770 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3772 client_lease = existing_lease;
3800 auto const& classes = ctx.
query_->getClasses();
3802 while (current_subnet) {
3811 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3838 const bool fwd_dns_update,
3839 const bool rev_dns_update,
3840 const std::string& hostname,
3841 const bool fake_allocation,
3842 const uint32_t offer_lft)
3862 if (host !=
hosts_.cend()) {
3863 return (host->second);
3873 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3874 if (host !=
hosts_.cend()) {
3875 return (host->second);
3885 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3886 return (ddns_params_);
3892 return (ddns_params_);
3914 auto const& classes = ctx.
query_->getClasses();
3915 if (subnet && !subnet->clientSupported(classes)) {
3916 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
3940 .arg(ctx.
query_->getLabel())
3958 !subnet->getReservationsInSubnet()) {
3964 subnet->getReservationsGlobal()) {
3967 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3970 if (!subnet->getReservationsInSubnet()) {
3976 std::map<SubnetID, ConstHostPtr> host_map;
3978 subnet->getSharedNetwork(network);
3987 const bool use_single_query = network &&
3991 if (use_single_query) {
3995 id_pair.second.size());
3999 for (
auto const& host : hosts) {
4000 if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
4001 host_map[host->getIPv4SubnetID()] = host;
4007 auto const& classes = ctx.
query_->getClasses();
4013 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
4016 if (use_single_query) {
4017 if (host_map.count(subnet->getID()) > 0) {
4018 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
4026 id_pair.second.size());
4029 ctx.
hosts_[subnet->getID()] = host;
4039 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
4045 for (
auto const& host : ctx.
hosts_) {
4046 host.second->encapsulateOptions();
4056 &id_pair.second[0], id_pair.second.size());
4073 findClientLease(ctx, client_lease);
4086 if (hasAddressReservation(ctx)) {
4090 .arg(ctx.
query_->getLabel())
4091 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
4097 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
4104 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
4108 .arg(ctx.
query_->getLabel())
4109 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4114 "v4-reservation-conflicts"),
4115 static_cast<int64_t
>(1));
4117 static_cast<int64_t
>(1));
4121 new_lease = renewLease4(client_lease, ctx);
4134 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
4135 !addressReserved(client_lease->addr_, ctx)) {
4139 .arg(ctx.
query_->getLabel());
4145 (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
4149 new_lease = renewLease4(client_lease, ctx);
4166 .arg(ctx.
query_->getLabel());
4179 .arg(ctx.
query_->getLabel());
4181 new_lease = allocateUnreservedLease4(ctx);
4202 "assigned-addresses"),
4203 static_cast<int64_t
>(-1));
4206 ->getBySubnetId(lease->subnet_id_);
4208 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4212 "assigned-addresses")),
4213 static_cast<int64_t
>(-1));
4225 findClientLease(ctx, client_lease);
4241 .arg(ctx.
query_->getLabel())
4247 }
else if (hasAddressReservation(ctx)) {
4256 .arg(ctx.
query_->getLabel())
4268 if (existing && !existing->expired() &&
4269 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4274 .arg(ctx.
query_->getLabel())
4284 if (hasAddressReservation(ctx) &&
4292 if (!existing || existing->expired()) {
4296 .arg(ctx.
query_->getLabel())
4297 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4307 if ((!hasAddressReservation(ctx) ||
4313 .arg(ctx.
query_->getLabel())
4325 if (((client_lease && existing) && (client_lease->addr_ != existing->addr_) &&
4327 (existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4330 auto conflicted_lease = client_lease;
4331 client_lease = existing;
4348 ((hasAddressReservation(ctx) &&
4350 inAllowedPool(ctx, client_lease->addr_))) {
4354 .arg(ctx.
query_->getLabel())
4356 return (renewLease4(client_lease, ctx));
4370 .arg(ctx.
query_->getLabel())
4385 .arg(ctx.
query_->getLabel());
4390 new_lease = allocateUnreservedLease4(ctx);
4396 if (new_lease && client_lease) {
4401 .arg(ctx.
query_->getLabel())
4402 .arg(client_lease->addr_.toText());
4423 if (!classes.
empty()) {
4429 for (
auto const& name : classes) {
4431 if (cl && (!cl->getOfferLft().unspecified())) {
4432 offer_lft = cl->getOfferLft();
4440 offer_lft = ctx.
subnet_->getOfferLft();
4449 if (ctx.
query_->inClass(
"BOOTP")) {
4454 uint32_t requested_lft = 0;
4457 OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
4459 requested_lft = opt_lft->getValue();
4467 if (!classes.
empty()) {
4473 for (
auto const& name : classes) {
4475 if (cl && (!cl->getValid().unspecified())) {
4476 candidate_lft = cl->getValid();
4483 if (!candidate_lft) {
4484 candidate_lft = ctx.
subnet_->getValid();
4489 if (requested_lft > 0) {
4490 return (candidate_lft.
get(requested_lft));
4494 return (candidate_lft.
get());
4500 if (ctx.
query_->inClass(
"BOOTP")) {
4509 if (!classes.
empty()) {
4515 for (
auto const& name : classes) {
4517 if (cl && (!cl->getValid().unspecified())) {
4518 candidate_lft = cl->getValid();
4525 if (!candidate_lft) {
4526 candidate_lft = ctx.
subnet_->getValid();
4530 uint32_t remain(valid);
4533 valid = candidate_lft.
getMin();
4536 if (remain > valid) {
4544 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
4545 if (!threshold.unspecified() && (threshold < 1.0)) {
4547 getOccupancyRate(addr, ctx.
query_->getClasses());
4548 if (occupancy >= threshold) {
4557AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
4560 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
4563 isc_throw(BadValue,
"Can't create a lease without a subnet");
4567 uint32_t valid_lft = ctx.offer_lft_;
4569 if (useMinValidLft(ctx, addr)) {
4576 time_t now = time(0);
4579 if (ctx.subnet_->getMatchClientId()) {
4580 client_id = ctx.clientid_;
4583 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
4584 valid_lft, now, ctx.subnet_->getID()));
4587 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
4588 lease->fqdn_rev_ = ctx.rev_dns_update_;
4589 lease->hostname_ = ctx.hostname_;
4595 if (ctx.callout_handle_ &&
4602 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
4605 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
4609 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
4616 boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
4617 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
4620 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
4623 ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
4626 ctx.callout_handle_->setArgument(
"lease4", lease);
4631 callout_status = ctx.callout_handle_->getStatus();
4643 ctx.callout_handle_->getArgument(
"lease4", lease);
4646 if (ctx.fake_allocation_ && ctx.offer_lft_) {
4650 lease->fqdn_fwd_ =
false;
4651 lease->fqdn_rev_ =
false;
4654 if (!ctx.fake_allocation_ || ctx.offer_lft_) {
4655 auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4657 lease->pool_id_ = pool->getID();
4666 "assigned-addresses"),
4667 static_cast<int64_t
>(1));
4671 "cumulative-assigned-addresses"),
4672 static_cast<int64_t
>(1));
4678 "assigned-addresses")),
4679 static_cast<int64_t
>(1));
4684 "cumulative-assigned-addresses")),
4685 static_cast<int64_t
>(1));
4720 time_t now = time(0);
4722 if (lease->cltt_ > now) {
4725 uint32_t age = now - lease->cltt_;
4727 if (age >= lease->valid_lft_) {
4730 valid = lease->valid_lft_ - age;
4734AllocEngine::renewLease4(
const Lease4Ptr& lease,
4744 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4749 lease->reuseable_valid_lft_ = 0;
4750 if (!updateLease4Information(lease, ctx)) {
4751 setLeaseReusable(lease, ctx);
4776 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4783 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4792 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4818 lease->pool_id_ = pool->getID();
4828 "assigned-addresses"),
4829 static_cast<int64_t
>(1));
4833 "cumulative-assigned-addresses"),
4834 static_cast<int64_t
>(1));
4840 "assigned-addresses")),
4841 static_cast<int64_t
>(1));
4846 "cumulative-assigned-addresses")),
4847 static_cast<int64_t
>(1));
4858 *lease = *old_values;
4865AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4866 AllocEngine::ClientContext4& ctx,
4869 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
4873 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
4884 expired->reuseable_valid_lft_ = 0;
4885 static_cast<void>(updateLease4Information(expired, ctx));
4889 .arg(ctx.
query_->getLabel())
4890 .arg(expired->toText());
4897 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4914 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4948 expired->pool_id_ = pool->getID();
4956 "assigned-addresses"),
4957 static_cast<int64_t
>(1));
4961 "cumulative-assigned-addresses"),
4962 static_cast<int64_t
>(1));
4968 "assigned-addresses")),
4969 static_cast<int64_t
>(1));
4974 "cumulative-assigned-addresses")),
4975 static_cast<int64_t
>(1));
4992AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate,
ClientContext4& ctx,
4994 ctx.conflicting_lease_.reset();
4998 if (exist_lease->expired()) {
4999 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5003 ctx.old_lease_->hostname_.clear();
5004 ctx.old_lease_->fqdn_fwd_ =
false;
5005 ctx.old_lease_->fqdn_rev_ =
false;
5006 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
5012 ctx.conflicting_lease_ = exist_lease;
5016 return (createLease4(ctx, candidate, callout_status));
5036 ctx.subnet_->getSharedNetwork(network);
5043 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
5057 uint64_t subnets_with_unavail_leases = 0;
5060 uint64_t subnets_with_unavail_pools = 0;
5062 auto const& classes = ctx.query_->getClasses();
5066 if (subnet->getMatchClientId()) {
5067 client_id = ctx.clientid_;
5079 (attempts_ == 0 || possible_attempts < attempts_) ?
5083 if (max_attempts > 0) {
5086 ++subnets_with_unavail_leases;
5090 ++subnets_with_unavail_pools;
5093 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
5098 for (
uint128_t i = 0; i < max_attempts; ++i) {
5103 IOAddress candidate = allocator->pickAddress(classes,
5105 ctx.requested_address_);
5112 if (exclude_first_last_24) {
5114 auto const& bytes = candidate.
toBytes();
5115 if ((bytes.size() != 4) ||
5116 (bytes[3] == 0) || (bytes[3] == 255U)) {
5123 if (check_reservation_first && addressReserved(candidate, ctx)) {
5130 ResourceHandler4 resource_handler;
5132 !resource_handler.
tryLock4(candidate)) {
5141 if (check_reservation_first || !addressReserved(candidate, ctx)) {
5143 new_lease = createLease4(ctx, candidate, callout_status);
5147 if (exist_lease->expired() &&
5148 (check_reservation_first || !addressReserved(candidate, ctx))) {
5149 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5150 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
5168 subnet = subnet->getNextSubnet(original_subnet, classes);
5171 ctx.subnet_ = subnet;
5180 .arg(ctx.query_->getLabel())
5181 .arg(network->getName())
5182 .arg(subnets_with_unavail_leases)
5183 .arg(subnets_with_unavail_pools);
5185 static_cast<int64_t
>(1));
5188 "v4-allocation-fail-shared-network"),
5189 static_cast<int64_t
>(1));
5193 std::string shared_network = ctx.subnet_->getSharedNetworkName();
5194 if (shared_network.empty()) {
5195 shared_network =
"(none)";
5198 .arg(ctx.query_->getLabel())
5199 .arg(ctx.subnet_->toText())
5200 .arg(ctx.subnet_->getID())
5201 .arg(shared_network);
5203 static_cast<int64_t
>(1));
5206 "v4-allocation-fail-subnet"),
5207 static_cast<int64_t
>(1));
5209 if (total_attempts == 0) {
5215 .arg(ctx.query_->getLabel());
5217 static_cast<int64_t
>(1));
5220 "v4-allocation-fail-no-pools"),
5221 static_cast<int64_t
>(1));
5228 .arg(ctx.query_->getLabel())
5229 .arg(total_attempts);
5231 static_cast<int64_t
>(1));
5234 "v4-allocation-fail"),
5235 static_cast<int64_t
>(1));
5238 if (!classes.empty()) {
5240 .arg(ctx.query_->getLabel())
5241 .arg(classes.toText());
5243 static_cast<int64_t
>(1));
5246 "v4-allocation-fail-classes"),
5247 static_cast<int64_t
>(1));
5254AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
5255 AllocEngine::ClientContext4& ctx)
const {
5256 bool changed =
false;
5257 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
5259 lease->subnet_id_ = ctx.
subnet_->getID();
5261 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
5263 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
5268 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
5272 }
else if (lease->client_id_) {
5276 uint32_t remain_lft(0);
5278 lease->cltt_ = time(0);
5282 if (!lease->valid_lft_) {
5283 if (useMinValidLft(ctx, lease->addr_)) {
5284 lease->valid_lft_ = remain_lft;
5292 if (lease->valid_lft_ != lease->current_valid_lft_) {
5316 bool changed =
false;
5319 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5334 sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
5343 extended_info->set(
"sub-options", relay_agent);
5347 std::vector<uint8_t> bytes = remote_id->toBinary();
5348 lease->remote_id_ = bytes;
5349 if (bytes.size() > 0) {
5350 extended_info->set(
"remote-id",
5357 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5358 lease->relay_id_ = bytes;
5359 if (bytes.size() > 0) {
5360 extended_info->set(
"relay-id",
5366 return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
5376 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5381 if (ctx.
query_->relay_info_.empty()) {
5396 for (
auto const& relay : ctx.
query_->relay_info_) {
5405 if (!relay.options_.empty()) {
5410 const uint8_t* cp = buf.
getData();
5411 std::vector<uint8_t> bytes;
5412 std::stringstream ss;
5420 if (remote_id_it != relay.options_.end()) {
5421 OptionPtr remote_id = remote_id_it->second;
5423 std::vector<uint8_t> bytes = remote_id->toBinary();
5424 if (bytes.size() > 0) {
5425 relay_elem->set(
"remote-id",
5432 if (relay_id_it != relay.options_.end()) {
5433 OptionPtr relay_id = relay_id_it->second;
5435 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5436 if (bytes.size() > 0) {
5437 relay_elem->set(
"relay-id",
5444 extended_info->add(relay_elem);
5448 if (lease->updateUserContextISC(
"relay-info", extended_info)) {
5454AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
5455 const ClientContext4& ctx)
const {
5457 lease->reuseable_valid_lft_ = 0;
5473 if (lease->cltt_ < lease->current_cltt_) {
5477 uint32_t age = lease->cltt_ - lease->current_cltt_;
5479 if (age >= lease->current_valid_lft_) {
5484 uint32_t max_age = 0;
5485 if (!subnet->getCacheMaxAge().unspecified()) {
5486 max_age = subnet->getCacheMaxAge().get();
5487 if ((max_age == 0) || (age > max_age)) {
5493 if (!subnet->getCacheThreshold().unspecified()) {
5494 double threshold = subnet->getCacheThreshold().get();
5495 if ((threshold <= 0.) || (threshold > 1.)) {
5498 max_age = lease->valid_lft_ * threshold;
5499 if (age > max_age) {
5510 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
5514AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
5515 uint32_t current_preferred_lft,
5518 lease->reuseable_valid_lft_ = 0;
5519 lease->reuseable_preferred_lft_ = 0;
5529 if (lease->cltt_ < lease->current_cltt_) {
5533 uint32_t age = lease->cltt_ - lease->current_cltt_;
5535 if (age >= lease->current_valid_lft_) {
5540 uint32_t max_age = 0;
5541 if (!subnet->getCacheMaxAge().unspecified()) {
5542 max_age = subnet->getCacheMaxAge().get();
5543 if ((max_age == 0) || (age > max_age)) {
5549 if (!subnet->getCacheThreshold().unspecified()) {
5550 double threshold = subnet->getCacheThreshold().get();
5551 if ((threshold <= 0.) || (threshold > 1.)) {
5554 max_age = lease->valid_lft_ * threshold;
5555 if (age > max_age) {
5567 (current_preferred_lft == 0)) {
5569 lease->reuseable_preferred_lft_ = current_preferred_lft;
5570 }
else if (current_preferred_lft > age) {
5571 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
5579 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_SKIP
skip the next processing step
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Notes: IntElement type is changed to int64_t.
Multiple lease records found where one expected.
static IPv6Resrv makeIPv6Resrv(const Lease6 &lease)
Creates an IPv6Resrv instance from a Lease6.
void updateLease6ExtendedInfo(const Lease6Ptr &lease, const ClientContext6 &ctx) const
Stores additional client query parameters on a V6 lease.
static void getMinValidLft(const ClientContext4 &ctx, uint32_t &valid)
Returns the valid lifetime based on the v4 context when the pool occupancy is over the adaptive lease...
void reclaimExpiredLeases6Internal(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Body of reclaimExpiredLeases6.
bool updateLease4ExtendedInfo(const Lease4Ptr &lease, const ClientContext4 &ctx) const
Stores additional client query parameters on a V4 lease.
static ConstHostPtr findGlobalReservation(ClientContext6 &ctx)
Attempts to find the host reservation for the client.
AllocEngine(isc::util::uint128_t const &attempts)
Constructor.
std::pair< Host::IdentifierType, std::vector< uint8_t > > IdentifierPair
A tuple holding host identifier type and value.
void clearReclaimedExtendedInfo(const Lease4Ptr &lease) const
Clear extended info from a reclaimed V4 lease.
isc::util::ReadWriteMutex rw_mutex_
The read-write mutex.
static void getLifetimes6(ClientContext6 &ctx, uint32_t &preferred, uint32_t &valid)
Determines the preferred and valid v6 lease lifetimes.
static void findReservation(ClientContext6 &ctx)
static uint32_t getOfferLft(const ClientContext4 &ctx, bool only_on_discover=true)
Returns the offer lifetime based on the v4 context.
void reclaimExpiredLeases4Internal(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Body of reclaimExpiredLeases4.
void deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
static uint32_t getValidLft(const ClientContext4 &ctx)
Returns the valid lifetime based on the v4 context.
void reclaimExpiredLeases6(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Reclaims expired IPv6 leases.
static std::string labelNetworkOrSubnet(ConstSubnetPtr subnet)
Generates a label for subnet or shared-network from subnet.
void reclaimExpiredLeases4(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Reclaims expired IPv4 leases.
static void getMinLifetimes6(ClientContext6 &ctx, uint32_t &preferred, uint32_t &valid)
Determines the preferred and valid v6 lease lifetimes when the pool occupancy is over the adaptive le...
static void getRemaining(const Lease4Ptr &lease, uint32_t &valid)
Set remaining valid life time.
Lease4Ptr allocateLease4(ClientContext4 &ctx)
Returns IPv4 lease.
void deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
Lease6Collection allocateLeases6(ClientContext6 &ctx)
Allocates IPv6 leases for a given IA container.
Lease6Collection renewLeases6(ClientContext6 &ctx)
Renews existing DHCPv6 leases for a given IA.
PrefixLenMatchType
Type of preferred PD-pool prefix length selection criteria.
static bool isValidPrefixPool(Allocator::PrefixLenMatchType prefix_length_match, PoolPtr pool, uint8_t hint_prefix_length)
Check if the pool matches the selection criteria relative to the provided hint prefix length.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Container for storing client class names.
bool empty() const
Check if classes is empty.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
ConstHostCollection getAll6(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv6 subnet.
ConstHostCollection getAll4(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv4 subnet.
ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
bool getDisableSingleQuery() const
Returns the disable single query flag.
static HostMgr & instance()
Returns a sole instance of the HostMgr.
ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv4 subnet.
ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv6 subnet.
IPv6 reservation for a host.
Type
Type of the reservation.
static TrackingLeaseMgr & instance()
Return current lease manager.
virtual Lease6Collection getLeases6(Lease::Type type, const DUID &duid, uint32_t iaid) const =0
Returns existing IPv6 leases for a given DUID+IA combination.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv6 leases.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv6 leases.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv4 leases.
virtual bool addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv4 leases.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
static void packOptions6(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options)
Stores DHCPv6 options in a buffer.
Attempt to update lease that was not there.
static std::string makeLabel(const HWAddrPtr &hwaddr, const ClientIdPtr &client_id, const uint32_t transid)
Returns text representation of the given packet identifiers.
static std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
static bool subnetsIncludeMatchClientId(const ConstSubnet4Ptr &first_subnet, const ClientClasses &client_classes)
Checks if the shared network includes a subnet with the match client ID flag set to true.
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_SKIP
skip the next processing step
static int registerHook(const std::string &name)
Register Hook.
static bool calloutsPresent(int index)
Are callouts present?
static boost::shared_ptr< CalloutHandle > createCalloutHandle()
Return callout handle.
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
Wrapper class around callout handle which automatically resets handle's state.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
bool getMode() const
Get the multi-threading mode.
A template representing an optional value.
T get() const
Retrieves the encapsulated value.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
const uint8_t * getData() const
Return a pointer to the head of the data stored in the buffer.
size_t getLength() const
Return the length of data written in the buffer.
Utility class to measure code execution times.
long getTotalMilliseconds() const
Retrieves the total measured duration in milliseconds.
void stop()
Stops the stopwatch.
std::string logFormatTotalDuration() const
Returns the total measured duration in the format directly usable in the log messages.
This template specifies a parameter value.
T get(T hint) const
Returns value with a hint.
T getMin() const
Returns a minimum allowed value.
Write mutex RAII handler.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_INVALID
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAMATION_FAILED
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_NO_POOLS
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS6
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RECOVER_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_IN_USE
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_HR
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_PREFIX_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_V6_HR
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_ADDR_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_ERROR
const isc::log::MessageID ALLOC_ENGINE_V6_HINT_RESERVED
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_SLOW
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED
isc::log::Logger alloc_engine_logger("alloc-engine")
Logger for the AllocEngine.
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE
const isc::log::MessageID ALLOC_ENGINE_LEASE_RECLAIMED
const int ALLOC_ENGINE_DBG_TRACE
Logging levels for the AllocEngine.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_COMPLETE
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_COMPLETE
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ERROR
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_HR
boost::shared_ptr< DUID > DuidPtr
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
const isc::log::MessageID ALLOC_ENGINE_V4_DECLINED_RECOVERED
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_SELECT_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_SLOW
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_USE_HR
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_TIMEOUT
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_START
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAIM
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAIM
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_HR
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_TIMEOUT
const isc::log::MessageID DHCPSRV_CFGMGR_IP_RESERVATIONS_UNIQUE_DUPLICATES_DETECTED
const isc::log::MessageID ALLOC_ENGINE_V6_HR_ADDR_GRANTED
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_CLASSES
const isc::log::MessageID ALLOC_ENGINE_V6_NO_MORE_EXPIRED_LEASES
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_ERROR
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_ADDR_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_NO_POOLS
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SHARED_NETWORK
const isc::log::MessageID ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
const int ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA
Records detailed results of various operations.
const int DHCPSRV_DBG_HOOKS
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_COMPLETE
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_PREFIX_LEASE
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
const isc::log::MessageID ALLOC_ENGINE_V4_NO_MORE_EXPIRED_LEASES
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_EXTEND_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_NEW_LEASE
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_SELECT_SKIP
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_RECOVER_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_COMPLETE
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_CALCULATED_PREFERRED_LIFETIME
void deleteAssignedLease(Lease4Ptr lease)
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_UNRESERVED
const isc::log::MessageID ALLOC_ENGINE_V6_DECLINED_RECOVERED
boost::shared_ptr< const Subnet > ConstSubnetPtr
A generic pointer to either const Subnet4 or const Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_START
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAMATION_FAILED
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SUBNET
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_ADDRESS_CONFLICT
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RENEW_SKIP
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SUBNET
const int ALLOC_ENGINE_DBG_TRACE_DETAIL
Record detailed traces.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SHARED_NETWORK
const isc::log::MessageID ALLOC_ENGINE_V6_HR_PREFIX_GRANTED
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_CLASSES
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
boost::multiprecision::checked_uint128_t uint128_t
Defines the logger used by the top-level component of kea-lfc.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
Context information for the DHCPv4 lease allocation.
ClientIdPtr clientid_
Client identifier from the DHCP message.
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
ConstHostPtr currentHost() const
Returns host for currently selected subnet.
ClientContext4()
Default constructor.
Pkt4Ptr query_
A pointer to the client's message.
Lease4Ptr new_lease_
A pointer to a newly allocated lease.
std::string hostname_
Hostname.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
ConstSubnet4Ptr subnet_
Subnet selected for the client by the server.
bool rev_dns_update_
Perform reverse DNS update.
uint32_t offer_lft_
If not zero, then we will allocate on DISCOVER for this amount of time.
bool fake_allocation_
Indicates if this is a real or fake allocation.
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
bool unknown_requested_addr_
True when the address DHCPREQUEST'ed by client is not within a dynamic pool the server knows about.
Lease4Ptr old_lease_
A pointer to an old lease that the client had before update.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
bool fwd_dns_update_
Perform forward DNS update.
asiolink::IOAddress requested_address_
An address that the client desires.
Lease4Ptr conflicting_lease_
A pointer to the object representing a lease in conflict.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
HWAddrPtr hwaddr_
HW address from the DHCP message.
IAContext()
Default constructor.
Lease6Collection old_leases_
A pointer to any old leases that the client had before update but are no longer valid after the updat...
Option6IAPtr ia_rsp_
A pointer to the IA_NA/IA_PD option to be sent in response.
Lease::Type type_
Lease type (IA or PD)
ResourceContainer new_resources_
Holds addresses and prefixes allocated for this IA.
bool isNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was new.
Lease6Collection changed_leases_
A pointer to any leases that have changed FQDN information.
void addHint(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128, const uint32_t preferred=0, const uint32_t valid=0)
Convenience method adding new hint.
void addNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding new prefix or address.
Lease6Collection reused_leases_
Set of leases marked for reuse by lease caching.
HintContainer hints_
Client's hints.
uint32_t iaid_
The IAID field from IA_NA or IA_PD that is being processed.
Context information for the DHCPv6 leases allocation.
IAContext & currentIA()
Returns IA specific context for the currently processed IA.
std::vector< IAContext > ias_
Container holding IA specific contexts.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
bool fake_allocation_
Indicates if this is a real or fake allocation.
ConstHostPtr currentHost() const
Returns host from the most preferred subnet.
ClientContext6()
Default constructor.
DuidPtr duid_
Client identifier.
void addAllocatedResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding allocated prefix or address.
Lease6Collection new_leases_
A collection of newly allocated leases.
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
bool isAllocated(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was allocated.
bool hasGlobalReservation(const IPv6Resrv &resv) const
Determines if a global reservation exists.
ResourceContainer allocated_resources_
Holds addresses and prefixes allocated for all IAs.
bool rev_dns_update_
A boolean value which indicates that server takes responsibility for the reverse DNS Update for this ...
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
Pkt6Ptr query_
A pointer to the client's message.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
std::string hostname_
Hostname.
ConstSubnet6Ptr host_subnet_
Subnet from which host reservations should be retrieved.
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
ConstSubnet6Ptr subnet_
Subnet selected for the client by the server.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
bool fwd_dns_update_
A boolean value which indicates that server takes responsibility for the forward DNS Update for this ...
Structure that holds a lease for IPv4 address.
@ ACTION_UPDATE
update extended info tables.
@ ACTION_DELETE
delete reference to the lease
@ ACTION_IGNORE
ignore extended info,
a common structure for IPv4 and IPv6 leases
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
static const uint32_t STATE_DEFAULT
A lease in the default state.
static const uint32_t STATE_DECLINED
Declined lease.
static const uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Type
Type of lease or pool.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
static const uint32_t STATE_REGISTERED
Registered self-generated lease.