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,
1143 if (ctx.hosts_.empty()) {
1146 .arg(ctx.query_->getLabel());
1157 for (
auto const& lease : existing_leases) {
1158 if (lease->valid_lft_ != 0 ||
1161 if ((ctx.hosts_.count(lease->subnet_id_) > 0) &&
1162 ctx.hosts_[lease->subnet_id_]->hasReservation(
makeIPv6Resrv(*lease))) {
1167 .arg(ctx.query_->getLabel())
1168 .arg(lease->typeToText(lease->type_))
1169 .arg(lease->addr_.toText());
1175 if (!ctx.host_subnet_) {
1177 ctx.subnet_->getSharedNetwork(network);
1182 ctx.host_subnet_ = network->getSubnet(lease->subnet_id_);
1193 ctx.subnet_ = ctx.host_subnet_;
1195 if (!host->getHostname().empty()) {
1202 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1203 static_cast<bool>(fqdn));
1218 auto const& classes = ctx.query_->getClasses();
1220 subnet = subnet->getNextSubnet(ctx.subnet_)) {
1222 SubnetID subnet_id = subnet->getID();
1225 if (!subnet->clientSupported(classes) || ctx.hosts_.count(subnet_id) == 0) {
1231 bool in_subnet = subnet->getReservationsInSubnet();
1235 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1237 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1238 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1242 if (ctx.isAllocated(addr, prefix_len)) {
1251 (subnet->getReservationsOutOfPool() &&
1252 subnet->inPool(ctx.currentIA().type_, addr))) {
1264 ctx.subnet_ = subnet;
1266 if (!ctx.host_subnet_) {
1267 ctx.host_subnet_ = subnet;
1268 if (!host->getHostname().empty()) {
1282 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1283 static_cast<bool>(fqdn));
1289 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1296 existing_leases.push_back(lease);
1301 .arg(ctx.query_->getLabel());
1305 .arg(
static_cast<int>(prefix_len))
1306 .arg(ctx.query_->getLabel());
1324 allocateGlobalReservedLeases6(ctx, existing_leases);
1339 for (
auto const& lease : existing_leases) {
1340 if ((lease->valid_lft_ != 0) &&
1346 .arg(ctx.query_->getLabel())
1347 .arg(lease->typeToText(lease->type_))
1348 .arg(lease->addr_.toText());
1354 if (!ghost->getHostname().empty()) {
1361 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1362 static_cast<bool>(fqdn));
1377 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1378 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1380 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1381 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1385 if (ctx.isAllocated(addr, prefix_len)) {
1397 bool valid_subnet =
false;
1398 auto subnet = ctx.subnet_;
1400 if (subnet->inRange(addr)) {
1401 valid_subnet =
true;
1405 subnet = subnet->getNextSubnet(ctx.subnet_);
1408 if (!valid_subnet) {
1411 .arg(ctx.query_->getLabel())
1417 ctx.subnet_ = subnet;
1420 if (!ghost->getHostname().empty()) {
1434 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1435 static_cast<bool>(fqdn));
1440 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1447 existing_leases.push_back(lease);
1452 .arg(ctx.query_->getLabel());
1456 .arg(
static_cast<int>(prefix_len))
1457 .arg(ctx.query_->getLabel());
1475AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1478 if (existing_leases.empty() || !ctx.subnet_) {
1483 if (!ctx.subnet_->getReservationsInSubnet() &&
1484 !ctx.subnet_->getReservationsGlobal()) {
1485 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1494 for (
auto const& candidate :
copy) {
1498 if ((ctx.hasGlobalReservation(resv)) ||
1499 ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
1500 (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1509 auto hosts = getIPv6Resrv(ctx.subnet_->getID(), candidate->addr_);
1514 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1515 candidate->addr_,
false)) {
1519 if (!hosts.empty()) {
1522 if (hosts.size() == 1) {
1525 .arg(ctx.query_->getLabel())
1526 .arg(candidate->addr_.
toText())
1527 .arg(ctx.duid_->toText())
1528 .arg(hosts.front()->getIdentifierAsText());
1531 .arg(ctx.query_->getLabel())
1532 .arg(candidate->addr_.
toText())
1533 .arg(
static_cast<int>(candidate->prefixlen_))
1534 .arg(ctx.duid_->toText())
1535 .arg(hosts.front()->getIdentifierAsText());
1540 .arg(ctx.query_->getLabel())
1541 .arg(candidate->addr_.
toText())
1542 .arg(ctx.duid_->toText())
1546 .arg(ctx.query_->getLabel())
1547 .arg(candidate->addr_.
toText())
1548 .arg(
static_cast<int>(candidate->prefixlen_))
1549 .arg(ctx.duid_->toText())
1568 "assigned-nas" :
"assigned-pds",
1569 static_cast<int64_t
>(-1));
1574 "assigned-nas" :
"assigned-pds"),
1575 static_cast<int64_t
>(-1));
1579 auto const& pool = subnet->getPool(ctx.currentIA().type_, candidate->addr_,
false);
1584 "pool" :
"pd-pool", pool->getID(),
1586 "assigned-nas" :
"assigned-pds")),
1587 static_cast<int64_t
>(-1));
1597 ctx.currentIA().old_leases_.push_back(candidate);
1600 removeLeases(existing_leases, candidate->addr_);
1605AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1612 for (
auto const& candidate :
copy) {
1616 if (inAllowedPool(ctx, candidate->type_,
1617 candidate->addr_,
false)) {
1633 "assigned-nas" :
"assigned-pds",
1634 static_cast<int64_t
>(-1));
1639 "assigned-nas" :
"assigned-pds"),
1640 static_cast<int64_t
>(-1));
1644 auto const& pool = subnet->getPool(candidate->type_, candidate->addr_,
false);
1649 "pool" :
"pd-pool", pool->getID(),
1651 "assigned-nas" :
"assigned-pds")),
1652 static_cast<int64_t
>(-1));
1657 ctx.currentIA().old_leases_.push_back(candidate);
1660 removeLeases(existing_leases, candidate->addr_);
1665AllocEngine::removeLeases(
Lease6Collection& container,
const asiolink::IOAddress& addr) {
1667 bool removed =
false;
1668 for (Lease6Collection::iterator lease = container.begin();
1669 lease != container.end(); ++lease) {
1670 if ((*lease)->addr_ == addr) {
1677 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1688 int total = existing_leases.size();
1695 for (Lease6Collection::iterator lease = existing_leases.begin();
1696 lease != existing_leases.end(); ++lease) {
1700 if (ctx.hasGlobalReservation(resv) ||
1701 ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
1702 (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1722 "assigned-nas" :
"assigned-pds",
1723 static_cast<int64_t
>(-1));
1728 "assigned-nas" :
"assigned-pds"),
1729 static_cast<int64_t
>(-1));
1733 auto const& pool = subnet->getPool(ctx.currentIA().type_, (*lease)->addr_,
false);
1738 "pool" :
"pd-pool", pool->getID(),
1740 "assigned-nas" :
"assigned-pds")),
1741 static_cast<int64_t
>(-1));
1748 ctx.currentIA().old_leases_.push_back(*lease);
1763 existing_leases.erase(std::remove(existing_leases.begin(),
1764 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1769useMinLifetimes6(AllocEngine::ClientContext6& ctx,
const IOAddress& addr,
1770 uint8_t prefix_len) {
1771 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
1772 if (!threshold.unspecified() && (threshold < 1.0)) {
1774 getOccupancyRate(addr, prefix_len, ctx.
query_->getClasses());
1775 if (occupancy >= threshold) {
1788 if (!expired->expired()) {
1789 isc_throw(BadValue,
"Attempt to recycle lease that is still valid");
1793 isc_throw(BadValue,
"Attempt to recycle registered address");
1800 if (!ctx.fake_allocation_) {
1804 reclaimExpiredLease(expired, ctx.callout_handle_);
1808 expired->iaid_ = ctx.currentIA().iaid_;
1809 expired->duid_ = ctx.duid_;
1810 expired->hwaddr_ = ctx.hwaddr_;
1813 expired->preferred_lft_ = 0;
1814 expired->valid_lft_ = 0;
1816 useMinLifetimes6(ctx, expired->addr_, prefix_len)) {
1819 getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
1821 expired->reuseable_valid_lft_ = 0;
1823 expired->cltt_ = time(0);
1824 expired->subnet_id_ = ctx.subnet_->getID();
1825 expired->hostname_ = ctx.hostname_;
1826 expired->fqdn_fwd_ = ctx.fwd_dns_update_;
1827 expired->fqdn_rev_ = ctx.rev_dns_update_;
1828 expired->prefixlen_ = prefix_len;
1833 .arg(ctx.query_->getLabel())
1834 .arg(expired->toText());
1837 if (ctx.callout_handle_ &&
1844 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
1847 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
1852 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1855 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1858 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1861 ctx.callout_handle_->setArgument(
"lease6", expired);
1866 callout_status = ctx.callout_handle_->getStatus();
1883 ctx.callout_handle_->getArgument(
"lease6", expired);
1886 if (!ctx.fake_allocation_) {
1890 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_,
false);
1892 expired->pool_id_ = pool->getID();
1900 if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
1904 "assigned-nas" :
"assigned-pds"),
1905 static_cast<int64_t
>(1));
1910 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
1911 static_cast<int64_t
>(1));
1917 "pool" :
"pd-pool", pool->getID(),
1919 "assigned-nas" :
"assigned-pds")),
1920 static_cast<int64_t
>(1));
1925 "pool" :
"pd-pool", pool->getID(),
1927 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
1928 static_cast<int64_t
>(1));
1932 "assigned-nas" :
"assigned-pds",
1933 static_cast<int64_t
>(1));
1936 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
1937 static_cast<int64_t
>(1));
1950void sanitizeLifetimes6(AllocEngine::ClientContext6& ctx,
1951 uint32_t& preferred, uint32_t& valid) {
1953 if (!preferred || preferred > valid) {
1954 preferred = ((valid * 5)/8);
1957 .arg(ctx.
query_->getLabel())
1970 if (!classes.
empty()) {
1977 for (
auto const& name : classes) {
1980 (cl && (!cl->getPreferred().unspecified()))) {
1981 candidate_preferred = cl->getPreferred();
1986 (cl && (!cl->getValid().unspecified()))) {
1987 candidate_valid = cl->getValid();
1990 if (have_both == 2) {
1997 if (!candidate_preferred) {
1998 candidate_preferred = ctx.
subnet_->getPreferred();
2002 if (!candidate_valid) {
2003 candidate_valid = ctx.
subnet_->getValid();
2007 preferred = candidate_preferred;
2008 valid = candidate_valid;
2022 sanitizeLifetimes6(ctx, preferred, valid);
2033 if (!classes.
empty()) {
2040 for (
auto const& name : classes) {
2043 (cl && (!cl->getPreferred().unspecified()))) {
2044 candidate_preferred = cl->getPreferred();
2049 (cl && (!cl->getValid().unspecified()))) {
2050 candidate_valid = cl->getValid();
2053 if (have_both == 2) {
2060 if (!candidate_preferred) {
2061 candidate_preferred = ctx.
subnet_->getPreferred();
2065 if (!candidate_valid) {
2066 candidate_valid = ctx.
subnet_->getValid();
2070 uint32_t remain_preferred(preferred);
2071 uint32_t remain_valid(valid);
2074 preferred = candidate_preferred.
getMin();
2075 valid = candidate_valid.
getMin();
2078 if (remain_preferred > preferred) {
2079 preferred = remain_preferred;
2081 if (remain_valid > valid) {
2082 valid = remain_valid;
2085 sanitizeLifetimes6(ctx, preferred, valid);
2097 uint32_t preferred = 0;
2100 useMinLifetimes6(ctx, addr, prefix_len)) {
2106 Lease6Ptr lease(
new Lease6(ctx.currentIA().type_, addr, ctx.duid_,
2107 ctx.currentIA().iaid_, preferred,
2108 valid, ctx.subnet_->getID(),
2109 ctx.hwaddr_, prefix_len));
2111 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2112 lease->fqdn_rev_ = ctx.rev_dns_update_;
2113 lease->hostname_ = ctx.hostname_;
2116 if (ctx.callout_handle_ &&
2123 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
2126 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2131 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
2134 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
2137 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
2140 ctx.callout_handle_->setArgument(
"lease6", lease);
2145 callout_status = ctx.callout_handle_->getStatus();
2157 ctx.callout_handle_->getArgument(
"lease6", lease);
2160 if (!ctx.fake_allocation_) {
2164 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2166 lease->pool_id_ = pool->getID();
2175 if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
2179 "assigned-nas" :
"assigned-pds"),
2180 static_cast<int64_t
>(1));
2185 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2186 static_cast<int64_t
>(1));
2192 "pool" :
"pd-pool", pool->getID(),
2194 "assigned-nas" :
"assigned-pds")),
2195 static_cast<int64_t
>(1));
2200 "pool" :
"pd-pool", pool->getID(),
2202 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2203 static_cast<int64_t
>(1));
2207 "assigned-nas" :
"assigned-pds",
2208 static_cast<int64_t
>(1));
2211 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2212 static_cast<int64_t
>(1));
2216 ctx.currentIA().addNewResource(addr, prefix_len);
2243 time_t now = time(0);
2245 if (lease->cltt_ > now) {
2248 uint32_t age = now - lease->cltt_;
2250 if (age >= lease->valid_lft_) {
2253 valid = lease->valid_lft_ - age;
2254 if (age >= lease->preferred_lft_) {
2257 preferred = lease->preferred_lft_ - age;
2280 for (
auto const& l : leases_subnet) {
2282 leases.push_back(l);
2285 subnet = subnet->getNextSubnet(ctx.
subnet_);
2288 if (!leases.empty()) {
2291 .arg(ctx.
query_->getLabel());
2295 removeNonmatchingReservedLeases6(ctx, leases);
2298 if (!ctx.
hosts_.empty()) {
2302 .arg(ctx.
query_->getLabel());
2305 allocateReservedLeases6(ctx, leases);
2311 removeNonreservedLeases6(ctx, leases);
2318 if (leases.empty()) {
2322 .arg(ctx.
query_->getLabel());
2324 leases = allocateUnreservedLeases6(ctx);
2328 for (
auto const& l : leases) {
2336 .arg(ctx.
query_->getLabel())
2337 .arg(l->typeToText(l->type_))
2339 extendLease6(ctx, l);
2342 if (!leases.empty()) {
2346 for (
auto const& lease : leases) {
2361 .arg(ctx.
query_->getLabel())
2371 if (!lease || !ctx.subnet_) {
2377 if (ctx.subnet_->getID() != lease->subnet_id_) {
2379 ctx.subnet_->getSharedNetwork(network);
2382 network->getSubnet(
SubnetID(lease->subnet_id_));
2386 ctx.subnet_ = subnet;
2394 (((lease->type_ !=
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
2395 !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
2410 "assigned-nas" :
"assigned-pds",
static_cast<int64_t
>(-1));
2415 "assigned-nas" :
"assigned-pds"),
2416 static_cast<int64_t
>(-1));
2418 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2423 "pool" :
"pd-pool", pool->getID(),
2425 "assigned-nas" :
"assigned-pds")),
2426 static_cast<int64_t
>(-1));
2430 ctx.currentIA().old_leases_.push_back(lease);
2437 .arg(ctx.query_->getLabel())
2438 .arg(lease->toText());
2443 bool changed =
false;
2446 uint32_t current_preferred_lft = lease->preferred_lft_;
2448 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2449 uint32_t remain_preferred_lft(0);
2450 uint32_t remain_valid_lft(0);
2451 getRemaining(lease, remain_preferred_lft, remain_valid_lft);
2452 lease->preferred_lft_ = remain_preferred_lft;
2453 lease->valid_lft_ = remain_valid_lft;
2456 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2460 if ((lease->preferred_lft_ != current_preferred_lft) ||
2461 (lease->valid_lft_ != lease->current_valid_lft_)) {
2465 lease->cltt_ = time(NULL);
2466 if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
2467 (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
2468 (lease->hostname_ != ctx.hostname_)) {
2470 lease->hostname_ = ctx.hostname_;
2471 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2472 lease->fqdn_rev_ = ctx.rev_dns_update_;
2474 if ((!ctx.hwaddr_ && lease->hwaddr_) ||
2476 (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
2478 lease->hwaddr_ = ctx.hwaddr_;
2486 .arg(ctx.query_->getLabel())
2487 .arg(lease->toText());
2491 int hook_point = ctx.query_->getType() ==
DHCPV6_RENEW ?
2492 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2500 ScopedCalloutHandleState callout_handle_state(callout_handle);
2503 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2506 callout_handle->setArgument(
"query6", ctx.query_);
2509 callout_handle->setArgument(
"lease6", lease);
2513 callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
2515 callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
2528 .arg(ctx.query_->getName());
2535 bool update_stats =
false;
2539 if (old_data->expired()) {
2540 reclaimExpiredLease(old_data, ctx.callout_handle_);
2544 if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
2545 update_stats =
true;
2558 setLeaseReusable(lease, current_preferred_lft, ctx);
2563 if (lease->reuseable_valid_lft_ == 0) {
2564 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2566 lease->pool_id_ = pool->getID();
2572 old_data->reuseable_valid_lft_ = lease->reuseable_valid_lft_;
2579 "assigned-nas" :
"assigned-pds"),
2580 static_cast<int64_t
>(1));
2585 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2586 static_cast<int64_t
>(1));
2588 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2593 "pool" :
"pd-pool", pool->getID(),
2595 "assigned-nas" :
"assigned-pds")),
2596 static_cast<int64_t
>(1));
2601 "pool" :
"pd-pool", pool->getID(),
2603 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2604 static_cast<int64_t
>(1));
2608 "assigned-nas" :
"assigned-pds",
2609 static_cast<int64_t
>(1));
2613 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2614 static_cast<int64_t
>(1));
2627 ctx.currentIA().changed_leases_.push_back(old_data);
2633 for (
auto const& lease_it : leases) {
2635 if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
2637 updated_leases.push_back(lease);
2641 lease->reuseable_valid_lft_ = 0;
2642 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2643 lease->fqdn_rev_ = ctx.rev_dns_update_;
2644 lease->hostname_ = ctx.hostname_;
2645 uint32_t current_preferred_lft = lease->preferred_lft_;
2646 if (lease->valid_lft_ == 0) {
2648 lease->preferred_lft_ = 0;
2650 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2653 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2656 if (!ctx.fake_allocation_) {
2657 bool update_stats =
false;
2665 if (inAllowedPool(ctx, ctx.currentIA().type_,
2666 lease->addr_,
true)) {
2667 update_stats =
true;
2672 !(lease->hasIdenticalFqdn(*lease_it)));
2674 lease->cltt_ = time(NULL);
2675 if (!fqdn_changed) {
2676 setLeaseReusable(lease, current_preferred_lft, ctx);
2679 if (lease->reuseable_valid_lft_ == 0) {
2680 ctx.currentIA().changed_leases_.push_back(lease_it);
2684 ctx.currentIA().reused_leases_.push_back(lease_it);
2691 "assigned-nas" :
"assigned-pds"),
2692 static_cast<int64_t
>(1));
2697 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2698 static_cast<int64_t
>(1));
2700 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2705 "pool" :
"pd-pool", pool->getID(),
2707 "assigned-nas" :
"assigned-pds")),
2708 static_cast<int64_t
>(1));
2713 "pool" :
"pd-pool", pool->getID(),
2715 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2716 static_cast<int64_t
>(1));
2720 "assigned-nas" :
"assigned-pds",
2721 static_cast<int64_t
>(1));
2724 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2725 static_cast<int64_t
>(1));
2729 updated_leases.push_back(lease);
2732 return (updated_leases);
2737 const uint16_t timeout,
2738 const bool remove_lease,
2739 const uint16_t max_unwarned_cycles) {
2748 max_unwarned_cycles);
2749 }
catch (
const std::exception& ex) {
2758 const uint16_t timeout,
2759 const bool remove_lease,
2760 const uint16_t max_unwarned_cycles) {
2770 bool incomplete_reclamation =
false;
2773 if (max_leases > 0) {
2782 if (leases.size() > max_leases) {
2784 incomplete_reclamation =
true;
2797 if (!leases.empty() &&
2802 size_t leases_processed = 0;
2803 for (
auto const& lease : leases) {
2811 reclaimExpiredLease(lease, remove_lease, callout_handle);
2814 reclaimExpiredLease(lease, remove_lease, callout_handle);
2818 }
catch (
const std::exception& ex) {
2820 .arg(lease->addr_.toText())
2831 if (!incomplete_reclamation) {
2832 if (leases_processed < leases.size()) {
2833 incomplete_reclamation =
true;
2850 .arg(leases_processed)
2855 if (incomplete_reclamation) {
2856 ++incomplete_v6_reclamations_;
2859 if ((max_unwarned_cycles > 0) &&
2860 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2862 .arg(max_unwarned_cycles);
2864 incomplete_v6_reclamations_ = 0;
2869 incomplete_v6_reclamations_ = 0;
2882 uint64_t deleted_leases = 0;
2888 }
catch (
const std::exception& ex) {
2895 .arg(deleted_leases);
2900 const uint16_t timeout,
2901 const bool remove_lease,
2902 const uint16_t max_unwarned_cycles) {
2911 max_unwarned_cycles);
2912 }
catch (
const std::exception& ex) {
2921 const uint16_t timeout,
2922 const bool remove_lease,
2923 const uint16_t max_unwarned_cycles) {
2933 bool incomplete_reclamation =
false;
2936 if (max_leases > 0) {
2945 if (leases.size() > max_leases) {
2947 incomplete_reclamation =
true;
2960 if (!leases.empty() &&
2965 size_t leases_processed = 0;
2966 for (
auto const& lease : leases) {
2974 reclaimExpiredLease(lease, remove_lease, callout_handle);
2977 reclaimExpiredLease(lease, remove_lease, callout_handle);
2981 }
catch (
const std::exception& ex) {
2983 .arg(lease->addr_.toText())
2994 if (!incomplete_reclamation) {
2995 if (leases_processed < leases.size()) {
2996 incomplete_reclamation =
true;
3013 .arg(leases_processed)
3018 if (incomplete_reclamation) {
3019 ++incomplete_v4_reclamations_;
3022 if ((max_unwarned_cycles > 0) &&
3023 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
3025 .arg(max_unwarned_cycles);
3027 incomplete_v4_reclamations_ = 0;
3032 incomplete_v4_reclamations_ = 0;
3039template<
typename LeasePtrType>
3041AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
3043 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
3047template<
typename LeasePtrType>
3049AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
3054 if (!lease->stateExpiredReclaimed()) {
3055 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
3060AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
3061 const DbReclaimMode& reclaim_mode,
3067 .arg(lease->addr_.toText())
3068 .arg(
static_cast<int>(lease->prefixlen_));
3074 bool skipped =
false;
3077 if (callout_handle) {
3083 ScopedCalloutHandleState callout_handle_state(callout_handle);
3085 callout_handle->deleteAllArguments();
3086 callout_handle->setArgument(
"lease6", lease);
3087 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3107 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3117 remove_lease = reclaimDeclined(lease);
3119 if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
3120 isc_throw(Unexpected,
"attempt to reuse a registered lease");
3123 remove_lease =
true;
3126 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3130 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
3132 &lease_mgr, ph::_1));
3144 "reclaimed-leases"),
3145 static_cast<int64_t
>(1));
3151 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3157 pool->getID(),
"reclaimed-leases")),
3158 static_cast<int64_t
>(1));
3174 static_cast<int64_t
>(-1));
3178 "assigned-nas" :
"assigned-pds",
3179 static_cast<int64_t
>(-1));
3184 "assigned-nas" :
"assigned-pds"),
3185 static_cast<int64_t
>(-1));
3188 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3193 "pool" :
"pd-pool", pool->getID(),
3195 "assigned-nas" :
"assigned-pds")),
3196 static_cast<int64_t
>(-1));
3203AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
3204 const DbReclaimMode& reclaim_mode,
3210 .arg(lease->addr_.toText());
3216 bool skipped =
false;
3218 if (callout_handle) {
3224 ScopedCalloutHandleState callout_handle_state(callout_handle);
3226 callout_handle->setArgument(
"lease4", lease);
3227 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3245 lease->hostname_.clear();
3246 lease->fqdn_fwd_ =
false;
3247 lease->fqdn_rev_ =
false;
3251 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3261 remove_lease = reclaimDeclined(lease);
3264 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3268 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
3270 &lease_mgr, ph::_1));
3282 "reclaimed-leases"),
3283 static_cast<int64_t
>(1));
3288 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3293 "reclaimed-leases")),
3294 static_cast<int64_t
>(1));
3308 "assigned-addresses"),
3309 static_cast<int64_t
>(-1));
3312 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3317 "assigned-addresses")),
3318 static_cast<int64_t
>(-1));
3329 uint64_t deleted_leases = 0;
3335 }
catch (
const std::exception& ex) {
3342 .arg(deleted_leases);
3346AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3361 callout_handle->setArgument(
"lease4", lease);
3371 .arg(lease->addr_.toText());
3377 .arg(lease->addr_.toText())
3378 .arg(lease->valid_lft_);
3384 "declined-addresses"),
3385 static_cast<int64_t
>(-1));
3388 "reclaimed-declined-addresses"),
3389 static_cast<int64_t
>(1));
3393 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3397 "declined-addresses")),
3398 static_cast<int64_t
>(-1));
3402 "reclaimed-declined-addresses")),
3403 static_cast<int64_t
>(1));
3408 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3410 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3418AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3430 ScopedCalloutHandleState callout_handle_state(callout_handle);
3433 callout_handle->setArgument(
"lease6", lease);
3443 .arg(lease->addr_.toText());
3449 .arg(lease->addr_.toText())
3450 .arg(lease->valid_lft_);
3456 "declined-addresses"),
3457 static_cast<int64_t
>(-1));
3460 "reclaimed-declined-addresses"),
3461 static_cast<int64_t
>(1));
3465 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3469 "declined-addresses")),
3470 static_cast<int64_t
>(-1));
3474 "reclaimed-declined-addresses")),
3475 static_cast<int64_t
>(1));
3480 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3482 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3491 lease->relay_id_.clear();
3492 lease->remote_id_.clear();
3493 if (lease->getContext()) {
3500 if (lease->getContext()) {
3506template<
typename LeasePtrType>
3507void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3508 const bool remove_lease,
3509 const std::function<
void (
const LeasePtrType&)>&
3510 lease_update_fun)
const {
3518 }
else if (lease_update_fun) {
3521 lease->reuseable_valid_lft_ = 0;
3522 lease->hostname_.clear();
3523 lease->fqdn_fwd_ =
false;
3524 lease->fqdn_rev_ =
false;
3527 lease_update_fun(lease);
3536 .arg(lease->addr_.toText());
3542 return(
"<empty subnet>");
3546 subnet->getSharedNetwork(network);
3547 std::ostringstream ss;
3549 ss <<
"shared-network: " << network->getName();
3551 ss <<
"subnet id: " << subnet->getID();
3590 (!ctx.
subnet_->getReservationsOutOfPool() ||
3601 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
3606 hosts.push_back(host);
3620 for (
auto const& host : hosts) {
3624 if (id_pair.first == host->getIdentifierType() &&
3625 id_pair.second == host->getIdentifier()) {
3633 return (!hosts.empty());
3655 if (ctx.
hosts_.empty()) {
3660 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3661 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3662 global_host->second->getIPv4Reservation() :
3671 if (subnet->getReservationsGlobal() &&
3673 (subnet->inRange(global_host_address))) {
3678 if (subnet->getReservationsInSubnet()) {
3679 auto host = ctx.
hosts_.find(subnet->getID());
3684 if (host != ctx.
hosts_.end() && host->second) {
3685 auto reservation = host->second->getIPv4Reservation();
3686 if (!reservation.isV4Zero() &&
3687 (!subnet->getReservationsOutOfPool() ||
3697 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3703 .arg(ctx.
query_->getLabel())
3704 .arg(global_host_address.toText())
3731 auto const& classes = ctx.
query_->getClasses();
3735 bool try_clientid_lookup = (ctx.
clientid_ &&
3739 if (try_clientid_lookup) {
3748 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3753 if (subnet->getMatchClientId()) {
3754 for (
auto const& l : leases_client_id) {
3755 if (l->subnet_id_ == subnet->getID()) {
3768 if (!client_lease && ctx.
hwaddr_) {
3774 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3776 if (subnet->getMatchClientId()) {
3782 for (
auto const& client_lease_it : leases_hw_address) {
3783 Lease4Ptr existing_lease = client_lease_it;
3784 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3785 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3787 client_lease = existing_lease;
3815 auto const& classes = ctx.
query_->getClasses();
3817 while (current_subnet) {
3826 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3853 const bool fwd_dns_update,
3854 const bool rev_dns_update,
3855 const std::string& hostname,
3856 const bool fake_allocation,
3857 const uint32_t offer_lft)
3877 if (host !=
hosts_.cend()) {
3878 return (host->second);
3888 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3889 if (host !=
hosts_.cend()) {
3890 return (host->second);
3900 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3901 return (ddns_params_);
3907 return (ddns_params_);
3929 auto const& classes = ctx.
query_->getClasses();
3930 if (subnet && !subnet->clientSupported(classes)) {
3931 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
3955 .arg(ctx.
query_->getLabel())
3973 !subnet->getReservationsInSubnet()) {
3979 subnet->getReservationsGlobal()) {
3982 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3985 if (!subnet->getReservationsInSubnet()) {
3991 std::map<SubnetID, ConstHostPtr> host_map;
3993 subnet->getSharedNetwork(network);
4002 const bool use_single_query = network &&
4006 if (use_single_query) {
4010 id_pair.second.size());
4014 for (
auto const& host : hosts) {
4015 if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
4016 host_map[host->getIPv4SubnetID()] = host;
4022 auto const& classes = ctx.
query_->getClasses();
4028 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
4031 if (use_single_query) {
4032 if (host_map.count(subnet->getID()) > 0) {
4033 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
4041 id_pair.second.size());
4044 ctx.
hosts_[subnet->getID()] = host;
4054 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
4060 for (
auto const& host : ctx.
hosts_) {
4061 host.second->encapsulateOptions();
4071 &id_pair.second[0], id_pair.second.size());
4088 findClientLease(ctx, client_lease);
4101 if (hasAddressReservation(ctx)) {
4105 .arg(ctx.
query_->getLabel())
4106 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
4112 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
4119 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
4123 .arg(ctx.
query_->getLabel())
4124 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4129 "v4-reservation-conflicts"),
4130 static_cast<int64_t
>(1));
4132 static_cast<int64_t
>(1));
4136 new_lease = renewLease4(client_lease, ctx);
4149 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
4150 !addressReserved(client_lease->addr_, ctx)) {
4154 .arg(ctx.
query_->getLabel());
4160 (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
4164 new_lease = renewLease4(client_lease, ctx);
4181 .arg(ctx.
query_->getLabel());
4194 .arg(ctx.
query_->getLabel());
4196 new_lease = allocateUnreservedLease4(ctx);
4217 "assigned-addresses"),
4218 static_cast<int64_t
>(-1));
4221 ->getBySubnetId(lease->subnet_id_);
4223 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4227 "assigned-addresses")),
4228 static_cast<int64_t
>(-1));
4240 findClientLease(ctx, client_lease);
4256 .arg(ctx.
query_->getLabel())
4262 }
else if (hasAddressReservation(ctx)) {
4271 .arg(ctx.
query_->getLabel())
4283 if (existing && !existing->expired() &&
4284 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4289 .arg(ctx.
query_->getLabel())
4299 if (hasAddressReservation(ctx) &&
4307 if (!existing || existing->expired()) {
4311 .arg(ctx.
query_->getLabel())
4312 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4322 if ((!hasAddressReservation(ctx) ||
4328 .arg(ctx.
query_->getLabel())
4340 if (((client_lease && existing) && (client_lease->addr_ != existing->addr_) &&
4342 (existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4345 auto conflicted_lease = client_lease;
4346 client_lease = existing;
4363 ((hasAddressReservation(ctx) &&
4365 inAllowedPool(ctx, client_lease->addr_))) {
4369 .arg(ctx.
query_->getLabel())
4371 return (renewLease4(client_lease, ctx));
4385 .arg(ctx.
query_->getLabel())
4400 .arg(ctx.
query_->getLabel());
4405 new_lease = allocateUnreservedLease4(ctx);
4411 if (new_lease && client_lease) {
4416 .arg(ctx.
query_->getLabel())
4417 .arg(client_lease->addr_.toText());
4438 if (!classes.
empty()) {
4444 for (
auto const& name : classes) {
4446 if (cl && (!cl->getOfferLft().unspecified())) {
4447 offer_lft = cl->getOfferLft();
4455 offer_lft = ctx.
subnet_->getOfferLft();
4464 if (ctx.
query_->inClass(
"BOOTP")) {
4469 uint32_t requested_lft = 0;
4472 OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
4474 requested_lft = opt_lft->getValue();
4482 if (!classes.
empty()) {
4488 for (
auto const& name : classes) {
4490 if (cl && (!cl->getValid().unspecified())) {
4491 candidate_lft = cl->getValid();
4498 if (!candidate_lft) {
4499 candidate_lft = ctx.
subnet_->getValid();
4504 if (requested_lft > 0) {
4505 return (candidate_lft.
get(requested_lft));
4509 return (candidate_lft.
get());
4515 if (ctx.
query_->inClass(
"BOOTP")) {
4524 if (!classes.
empty()) {
4530 for (
auto const& name : classes) {
4532 if (cl && (!cl->getValid().unspecified())) {
4533 candidate_lft = cl->getValid();
4540 if (!candidate_lft) {
4541 candidate_lft = ctx.
subnet_->getValid();
4545 uint32_t remain(valid);
4548 valid = candidate_lft.
getMin();
4551 if (remain > valid) {
4559 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
4560 if (!threshold.unspecified() && (threshold < 1.0)) {
4562 getOccupancyRate(addr, ctx.
query_->getClasses());
4563 if (occupancy >= threshold) {
4572AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
4575 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
4578 isc_throw(BadValue,
"Can't create a lease without a subnet");
4582 uint32_t valid_lft = ctx.offer_lft_;
4584 if (useMinValidLft(ctx, addr)) {
4591 time_t now = time(0);
4594 if (ctx.subnet_->getMatchClientId()) {
4595 client_id = ctx.clientid_;
4598 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
4599 valid_lft, now, ctx.subnet_->getID()));
4602 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
4603 lease->fqdn_rev_ = ctx.rev_dns_update_;
4604 lease->hostname_ = ctx.hostname_;
4610 if (ctx.callout_handle_ &&
4617 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
4620 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
4624 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
4631 boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
4632 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
4635 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
4638 ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
4641 ctx.callout_handle_->setArgument(
"lease4", lease);
4646 callout_status = ctx.callout_handle_->getStatus();
4658 ctx.callout_handle_->getArgument(
"lease4", lease);
4661 if (ctx.fake_allocation_ && ctx.offer_lft_) {
4665 lease->fqdn_fwd_ =
false;
4666 lease->fqdn_rev_ =
false;
4669 if (!ctx.fake_allocation_ || ctx.offer_lft_) {
4670 auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4672 lease->pool_id_ = pool->getID();
4681 "assigned-addresses"),
4682 static_cast<int64_t
>(1));
4686 "cumulative-assigned-addresses"),
4687 static_cast<int64_t
>(1));
4693 "assigned-addresses")),
4694 static_cast<int64_t
>(1));
4699 "cumulative-assigned-addresses")),
4700 static_cast<int64_t
>(1));
4735 time_t now = time(0);
4737 if (lease->cltt_ > now) {
4740 uint32_t age = now - lease->cltt_;
4742 if (age >= lease->valid_lft_) {
4745 valid = lease->valid_lft_ - age;
4749AllocEngine::renewLease4(
const Lease4Ptr& lease,
4759 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4764 lease->reuseable_valid_lft_ = 0;
4765 if (!updateLease4Information(lease, ctx)) {
4766 setLeaseReusable(lease, ctx);
4791 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4798 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4807 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4833 lease->pool_id_ = pool->getID();
4843 "assigned-addresses"),
4844 static_cast<int64_t
>(1));
4848 "cumulative-assigned-addresses"),
4849 static_cast<int64_t
>(1));
4855 "assigned-addresses")),
4856 static_cast<int64_t
>(1));
4861 "cumulative-assigned-addresses")),
4862 static_cast<int64_t
>(1));
4873 *lease = *old_values;
4880AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4881 AllocEngine::ClientContext4& ctx,
4884 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
4888 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
4899 expired->reuseable_valid_lft_ = 0;
4900 static_cast<void>(updateLease4Information(expired, ctx));
4904 .arg(ctx.
query_->getLabel())
4905 .arg(expired->toText());
4912 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4929 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4963 expired->pool_id_ = pool->getID();
4971 "assigned-addresses"),
4972 static_cast<int64_t
>(1));
4976 "cumulative-assigned-addresses"),
4977 static_cast<int64_t
>(1));
4983 "assigned-addresses")),
4984 static_cast<int64_t
>(1));
4989 "cumulative-assigned-addresses")),
4990 static_cast<int64_t
>(1));
5007AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate,
ClientContext4& ctx,
5009 ctx.conflicting_lease_.reset();
5013 if (exist_lease->expired()) {
5014 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5018 ctx.old_lease_->hostname_.clear();
5019 ctx.old_lease_->fqdn_fwd_ =
false;
5020 ctx.old_lease_->fqdn_rev_ =
false;
5021 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
5027 ctx.conflicting_lease_ = exist_lease;
5031 return (createLease4(ctx, candidate, callout_status));
5051 ctx.subnet_->getSharedNetwork(network);
5058 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
5072 uint64_t subnets_with_unavail_leases = 0;
5075 uint64_t subnets_with_unavail_pools = 0;
5077 auto const& classes = ctx.query_->getClasses();
5081 if (subnet->getMatchClientId()) {
5082 client_id = ctx.clientid_;
5094 (attempts_ == 0 || possible_attempts < attempts_) ?
5098 if (max_attempts > 0) {
5101 ++subnets_with_unavail_leases;
5105 ++subnets_with_unavail_pools;
5108 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
5113 for (
uint128_t i = 0; i < max_attempts; ++i) {
5118 IOAddress candidate = allocator->pickAddress(classes,
5120 ctx.requested_address_);
5127 if (exclude_first_last_24) {
5129 auto const& bytes = candidate.
toBytes();
5130 if ((bytes.size() != 4) ||
5131 (bytes[3] == 0) || (bytes[3] == 255U)) {
5138 if (check_reservation_first && addressReserved(candidate, ctx)) {
5145 ResourceHandler4 resource_handler;
5147 !resource_handler.
tryLock4(candidate)) {
5156 if (check_reservation_first || !addressReserved(candidate, ctx)) {
5158 new_lease = createLease4(ctx, candidate, callout_status);
5162 if (exist_lease->expired() &&
5163 (check_reservation_first || !addressReserved(candidate, ctx))) {
5164 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5165 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
5183 subnet = subnet->getNextSubnet(original_subnet, classes);
5186 ctx.subnet_ = subnet;
5195 .arg(ctx.query_->getLabel())
5196 .arg(network->getName())
5197 .arg(subnets_with_unavail_leases)
5198 .arg(subnets_with_unavail_pools);
5200 static_cast<int64_t
>(1));
5203 "v4-allocation-fail-shared-network"),
5204 static_cast<int64_t
>(1));
5208 std::string shared_network = ctx.subnet_->getSharedNetworkName();
5209 if (shared_network.empty()) {
5210 shared_network =
"(none)";
5213 .arg(ctx.query_->getLabel())
5214 .arg(ctx.subnet_->toText())
5215 .arg(ctx.subnet_->getID())
5216 .arg(shared_network);
5218 static_cast<int64_t
>(1));
5221 "v4-allocation-fail-subnet"),
5222 static_cast<int64_t
>(1));
5224 if (total_attempts == 0) {
5230 .arg(ctx.query_->getLabel());
5232 static_cast<int64_t
>(1));
5235 "v4-allocation-fail-no-pools"),
5236 static_cast<int64_t
>(1));
5243 .arg(ctx.query_->getLabel())
5244 .arg(total_attempts);
5246 static_cast<int64_t
>(1));
5249 "v4-allocation-fail"),
5250 static_cast<int64_t
>(1));
5253 if (!classes.empty()) {
5255 .arg(ctx.query_->getLabel())
5256 .arg(classes.toText());
5258 static_cast<int64_t
>(1));
5261 "v4-allocation-fail-classes"),
5262 static_cast<int64_t
>(1));
5269AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
5270 AllocEngine::ClientContext4& ctx)
const {
5271 bool changed =
false;
5272 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
5274 lease->subnet_id_ = ctx.
subnet_->getID();
5276 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
5278 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
5283 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
5287 }
else if (lease->client_id_) {
5291 uint32_t remain_lft(0);
5293 lease->cltt_ = time(0);
5297 if (!lease->valid_lft_) {
5298 if (useMinValidLft(ctx, lease->addr_)) {
5299 lease->valid_lft_ = remain_lft;
5307 if (lease->valid_lft_ != lease->current_valid_lft_) {
5331 bool changed =
false;
5334 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5349 sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
5358 extended_info->set(
"sub-options", relay_agent);
5362 std::vector<uint8_t> bytes = remote_id->toBinary();
5363 lease->remote_id_ = bytes;
5364 if (bytes.size() > 0) {
5365 extended_info->set(
"remote-id",
5372 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5373 lease->relay_id_ = bytes;
5374 if (bytes.size() > 0) {
5375 extended_info->set(
"relay-id",
5381 return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
5391 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5396 if (ctx.
query_->relay_info_.empty()) {
5411 for (
auto const& relay : ctx.
query_->relay_info_) {
5420 if (!relay.options_.empty()) {
5425 const uint8_t* cp = buf.
getData();
5426 std::vector<uint8_t> bytes;
5427 std::stringstream ss;
5435 if (remote_id_it != relay.options_.end()) {
5436 OptionPtr remote_id = remote_id_it->second;
5438 std::vector<uint8_t> bytes = remote_id->toBinary();
5439 if (bytes.size() > 0) {
5440 relay_elem->set(
"remote-id",
5447 if (relay_id_it != relay.options_.end()) {
5448 OptionPtr relay_id = relay_id_it->second;
5450 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5451 if (bytes.size() > 0) {
5452 relay_elem->set(
"relay-id",
5459 extended_info->add(relay_elem);
5463 if (lease->updateUserContextISC(
"relay-info", extended_info)) {
5469AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
5470 const ClientContext4& ctx)
const {
5472 lease->reuseable_valid_lft_ = 0;
5488 if (lease->cltt_ < lease->current_cltt_) {
5492 uint32_t age = lease->cltt_ - lease->current_cltt_;
5494 if (age >= lease->current_valid_lft_) {
5499 uint32_t max_age = 0;
5500 if (!subnet->getCacheMaxAge().unspecified()) {
5501 max_age = subnet->getCacheMaxAge().get();
5502 if ((max_age == 0) || (age > max_age)) {
5508 if (!subnet->getCacheThreshold().unspecified()) {
5509 double threshold = subnet->getCacheThreshold().get();
5510 if ((threshold <= 0.) || (threshold > 1.)) {
5513 max_age = lease->valid_lft_ * threshold;
5514 if (age > max_age) {
5525 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
5529AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
5530 uint32_t current_preferred_lft,
5533 lease->reuseable_valid_lft_ = 0;
5534 lease->reuseable_preferred_lft_ = 0;
5544 if (lease->cltt_ < lease->current_cltt_) {
5548 uint32_t age = lease->cltt_ - lease->current_cltt_;
5550 if (age >= lease->current_valid_lft_) {
5555 uint32_t max_age = 0;
5556 if (!subnet->getCacheMaxAge().unspecified()) {
5557 max_age = subnet->getCacheMaxAge().get();
5558 if ((max_age == 0) || (age > max_age)) {
5564 if (!subnet->getCacheThreshold().unspecified()) {
5565 double threshold = subnet->getCacheThreshold().get();
5566 if ((threshold <= 0.) || (threshold > 1.)) {
5569 max_age = lease->valid_lft_ * threshold;
5570 if (age > max_age) {
5582 (current_preferred_lft == 0)) {
5584 lease->reuseable_preferred_lft_ = current_preferred_lft;
5585 }
else if (current_preferred_lft > age) {
5586 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
5594 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())
Create a NullElement.
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, unsigned 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 constexpr uint32_t STATE_DEFAULT
A lease in the default state.
static constexpr uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
static constexpr uint32_t STATE_DECLINED
Declined lease.
static constexpr uint32_t STATE_REGISTERED
Registered self-generated lease.
static constexpr uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
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