37#include <boost/foreach.hpp>
38#include <boost/make_shared.hpp>
55namespace ph = std::placeholders;
60struct AllocEngineHooks {
61 int hook_index_lease4_select_;
62 int hook_index_lease4_renew_;
63 int hook_index_lease4_expire_;
64 int hook_index_lease4_recover_;
65 int hook_index_lease6_select_;
66 int hook_index_lease6_renew_;
67 int hook_index_lease6_rebind_;
68 int hook_index_lease6_expire_;
69 int hook_index_lease6_recover_;
89AllocEngineHooks
Hooks;
97 : attempts_(attempts), incomplete_v4_reclamations_(0),
98 incomplete_v6_reclamations_(0) {
101 hook_index_lease4_select_ =
Hooks.hook_index_lease4_select_;
102 hook_index_lease6_select_ =
Hooks.hook_index_lease6_select_;
129 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
134 reserved.push_back(host);
145 reserved.insert(reserved.end(), hosts.begin(), hosts.end());
164 const IOAddress& address,
bool check_subnet) {
168 auto const& classes = ctx.
query_->getClasses();
170 while (current_subnet) {
171 if (current_subnet->clientSupported(classes)) {
173 if (current_subnet->inPool(lease_type, address)) {
177 if (current_subnet->inPool(lease_type, address, classes)) {
183 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
210 const std::string& hostname,
211 const bool fake_allocation,
219 ias_(), ddns_params_() {
235 const uint8_t prefix_len,
236 const uint32_t preferred,
237 const uint32_t valid) {
247 addHint(iaaddr->getAddress(), 128,
248 iaaddr->getPreferred(), iaaddr->getValid());
257 addHint(iaprefix->getAddress(), iaprefix->getLength(),
258 iaprefix->getPreferred(), iaprefix->getValid());
264 const uint8_t prefix_len) {
271 const uint8_t prefix_len)
const {
279 const uint8_t prefix_len) {
287 return (
static_cast<bool>
294 if (subnet && subnet->getReservationsInSubnet()) {
295 auto host =
hosts_.find(subnet->getID());
296 if (host !=
hosts_.cend()) {
297 return (host->second);
307 if (subnet &&
subnet_->getReservationsGlobal()) {
308 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
309 if (host !=
hosts_.cend()) {
310 return (host->second);
320 return (ghost && ghost->hasReservation(resv));
326 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
327 return (ddns_params_);
333 return (ddns_params_);
352 !subnet->getReservationsInSubnet()) {
358 subnet->getReservationsGlobal()) {
361 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
364 if (!subnet->getReservationsInSubnet()) {
370 std::map<SubnetID, ConstHostPtr> host_map;
372 subnet->getSharedNetwork(network);
381 const bool use_single_query = network &&
385 if (use_single_query) {
389 id_pair.second.size());
393 for (
auto const& host : hosts) {
394 if (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL) {
395 host_map[host->getIPv6SubnetID()] = host;
401 auto const& classes = ctx.
query_->getClasses();
408 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
411 if (use_single_query) {
412 if (host_map.count(subnet->getID()) > 0) {
413 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
421 id_pair.second.size());
424 ctx.
hosts_[subnet->getID()] = host;
434 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
440 for (
auto const& host : ctx.
hosts_) {
441 host.second->encapsulateOptions();
451 &id_pair.second[0], id_pair.second.size());
485 for (
auto const& l : all_leases) {
487 ((l)->subnet_id_ == subnet->getID())) {
492 subnet = subnet->getNextSubnet(ctx.
subnet_);
512 if (leases.empty() && !ctx.
hosts_.empty()) {
516 .arg(ctx.
query_->getLabel());
521 allocateReservedLeases6(ctx, leases);
523 leases = updateLeaseData(ctx, leases);
538 }
else if (!leases.empty() && ctx.
hosts_.empty()) {
542 .arg(ctx.
query_->getLabel());
546 removeNonmatchingReservedLeases6(ctx, leases);
548 leases = updateLeaseData(ctx, leases);
557 }
else if (!leases.empty() && !ctx.
hosts_.empty()) {
561 .arg(ctx.
query_->getLabel());
565 allocateReservedLeases6(ctx, leases);
577 removeNonmatchingReservedLeases6(ctx, leases);
586 removeNonreservedLeases6(ctx, leases);
591 leases = updateLeaseData(ctx, leases);
604 if (leases.empty()) {
618 .arg(ctx.
query_->getLabel());
620 leases = allocateUnreservedLeases6(ctx);
623 if (!leases.empty()) {
627 for (
auto const& lease : leases) {
641 .arg(ctx.
query_->getLabel())
654 uint8_t hint_prefix_length = 128;
655 if (!ctx.currentIA().hints_.empty()) {
657 hint = ctx.currentIA().hints_[0].getAddress();
658 hint_prefix_length = ctx.currentIA().hints_[0].getPrefixLength();
667 uint64_t total_attempts = 0;
671 uint64_t subnets_with_unavail_leases = 0;
674 uint64_t subnets_with_unavail_pools = 0;
684 bool search_hint_lease =
true;
691 if (hint_prefix_length == 128) {
692 hint_prefix_length = 0;
694 if (!hint_prefix_length) {
702 Lease6Ptr lease = allocateBestMatch(ctx, hint_lease, search_hint_lease,
703 hint, hint_prefix_length, subnet,
704 network, total_attempts,
705 subnets_with_unavail_leases,
706 subnets_with_unavail_pools,
707 callout_status, prefix_length_match);
715 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
716 hint_prefix_length, subnet, network,
717 total_attempts, subnets_with_unavail_leases,
718 subnets_with_unavail_pools, callout_status,
719 prefix_length_match);
728 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
729 hint_prefix_length, subnet, network,
730 total_attempts, subnets_with_unavail_leases,
731 subnets_with_unavail_pools, callout_status,
732 prefix_length_match);
736 leases.push_back(lease);
740 auto const& classes = ctx.query_->getClasses();
746 .arg(ctx.query_->getLabel())
747 .arg(network->getName())
748 .arg(subnets_with_unavail_leases)
749 .arg(subnets_with_unavail_pools);
751 static_cast<int64_t
>(1));
754 "v6-allocation-fail-shared-network"),
755 static_cast<int64_t
>(1));
759 std::string shared_network = ctx.subnet_->getSharedNetworkName();
760 if (shared_network.empty()) {
761 shared_network =
"(none)";
764 .arg(ctx.query_->getLabel())
765 .arg(ctx.subnet_->toText())
766 .arg(ctx.subnet_->getID())
767 .arg(shared_network);
769 static_cast<int64_t
>(1));
772 "v6-allocation-fail-subnet"),
773 static_cast<int64_t
>(1));
775 if (total_attempts == 0) {
781 .arg(ctx.query_->getLabel());
783 static_cast<int64_t
>(1));
786 "v6-allocation-fail-no-pools"),
787 static_cast<int64_t
>(1));
794 .arg(ctx.query_->getLabel())
795 .arg(total_attempts);
797 static_cast<int64_t
>(1));
800 "v6-allocation-fail"),
801 static_cast<int64_t
>(1));
804 if (!classes.empty()) {
806 .arg(ctx.query_->getLabel())
807 .arg(classes.toText());
809 static_cast<int64_t
>(1));
812 "v6-allocation-fail-classes"),
813 static_cast<int64_t
>(1));
823 bool& search_hint_lease,
824 const isc::asiolink::IOAddress& hint_addr,
825 uint8_t hint_prefix_length,
828 uint64_t& total_attempts,
829 uint64_t& subnets_with_unavail_leases,
830 uint64_t& subnets_with_unavail_pools,
833 auto const& classes = ctx.query_->getClasses();
838 if (!search_hint_lease) {
839 usable_hint_lease = hint_lease;
841 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
842 if (!subnet->clientSupported(classes)) {
846 ctx.subnet_ = subnet;
850 pool = boost::dynamic_pointer_cast<Pool6>
851 (subnet->getPool(ctx.currentIA().type_, classes, hint_addr));
854 if (!pool || !pool->clientSupported(classes)) {
860 hint_prefix_length)) {
864 isc::asiolink::IOAddress hint = hint_addr;
873 bool in_subnet = subnet->getReservationsInSubnet();
876 if (search_hint_lease) {
877 search_hint_lease =
false;
879 usable_hint_lease = hint_lease;
881 if (!usable_hint_lease) {
893 (!subnet->getReservationsOutOfPool() ||
894 !subnet->inPool(ctx.currentIA().type_, hint))) {
895 hosts = getIPv6Resrv(subnet->getID(), hint);
905 Lease6Ptr new_lease = createLease6(ctx, hint, pool->getLength(), callout_status);
918 .arg(ctx.query_->getLabel())
922 }
else if (usable_hint_lease->expired() &&
932 (!subnet->getReservationsOutOfPool() ||
933 !subnet->inPool(ctx.currentIA().type_, hint))) {
934 hosts = getIPv6Resrv(subnet->getID(), hint);
942 Lease6Ptr old_lease(
new Lease6(*usable_hint_lease));
943 ctx.currentIA().old_leases_.push_back(old_lease);
946 Lease6Ptr lease = reuseExpiredLease(usable_hint_lease, ctx,
956 .arg(ctx.query_->getLabel())
968 if (!check_reservation_first) {
982 original_subnet->getSharedNetwork(network);
989 original_subnet = network->getPreferredSubnet(original_subnet, ctx.currentIA().type_);
992 ctx.subnet_ = subnet = original_subnet;
994 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
995 if (!subnet->clientSupported(classes)) {
1006 subnet->getPoolCapacity(ctx.currentIA().type_,
1008 prefix_length_match,
1009 hint_prefix_length);
1017 (attempts_ == 0 || possible_attempts < attempts_) ?
1021 if (max_attempts > 0) {
1024 ++subnets_with_unavail_leases;
1028 ++subnets_with_unavail_pools;
1032 bool in_subnet = subnet->getReservationsInSubnet();
1033 bool out_of_pool = subnet->getReservationsOutOfPool();
1038 if (ctx.callout_handle_) {
1042 for (uint64_t i = 0; i < max_attempts; ++i) {
1045 auto allocator = subnet->getAllocator(ctx.currentIA().type_);
1050 uint8_t prefix_len = 128;
1052 candidate = allocator->pickPrefix(classes, pool, ctx.duid_,
1053 prefix_length_match, hint_addr,
1054 hint_prefix_length);
1056 prefix_len = pool->getLength();
1059 candidate = allocator->pickAddress(classes, ctx.duid_, hint_addr);
1068 if (check_reservation_first && in_subnet && !out_of_pool) {
1069 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1070 if (!hosts.empty()) {
1078 ResourceHandler resource_handler;
1080 !resource_handler.
tryLock(ctx.currentIA().type_, candidate)) {
1093 if (!check_reservation_first && in_subnet && !out_of_pool) {
1094 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1095 if (!hosts.empty()) {
1104 ctx.subnet_ = subnet;
1105 Lease6Ptr new_lease = createLease6(ctx, candidate, prefix_len, callout_status);
1109 ctx.currentIA().old_leases_.clear();
1113 }
else if (ctx.callout_handle_ &&
1122 }
else if (existing->expired() &&
1125 if (!check_reservation_first && in_subnet && !out_of_pool) {
1126 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1127 if (!hosts.empty()) {
1135 Lease6Ptr old_lease(
new Lease6(*existing));
1136 ctx.currentIA().old_leases_.push_back(old_lease);
1138 ctx.subnet_ = subnet;
1139 existing = reuseExpiredLease(existing, ctx, prefix_len,
1153 if (ctx.hosts_.empty()) {
1156 .arg(ctx.query_->getLabel());
1167 for (
auto const& lease : existing_leases) {
1168 if (lease->valid_lft_ != 0 ||
1171 if ((ctx.hosts_.count(lease->subnet_id_) > 0) &&
1172 ctx.hosts_[lease->subnet_id_]->hasReservation(
makeIPv6Resrv(*lease))) {
1177 .arg(ctx.query_->getLabel())
1178 .arg(lease->typeToText(lease->type_))
1179 .arg(lease->addr_.toText());
1185 if (!ctx.host_subnet_) {
1187 ctx.subnet_->getSharedNetwork(network);
1192 ctx.host_subnet_ = network->getSubnet(lease->subnet_id_);
1203 ctx.subnet_ = ctx.host_subnet_;
1205 if (!host->getHostname().empty()) {
1212 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1213 static_cast<bool>(fqdn));
1228 auto const& classes = ctx.query_->getClasses();
1230 subnet = subnet->getNextSubnet(ctx.subnet_)) {
1232 SubnetID subnet_id = subnet->getID();
1235 if (!subnet->clientSupported(classes) || ctx.hosts_.count(subnet_id) == 0) {
1241 bool in_subnet = subnet->getReservationsInSubnet();
1245 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1247 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1248 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1252 if (ctx.isAllocated(addr, prefix_len)) {
1261 (subnet->getReservationsOutOfPool() &&
1262 subnet->inPool(ctx.currentIA().type_, addr))) {
1274 ctx.subnet_ = subnet;
1276 if (!ctx.host_subnet_) {
1277 ctx.host_subnet_ = subnet;
1278 if (!host->getHostname().empty()) {
1292 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1293 static_cast<bool>(fqdn));
1299 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1306 existing_leases.push_back(lease);
1311 .arg(ctx.query_->getLabel());
1315 .arg(
static_cast<int>(prefix_len))
1316 .arg(ctx.query_->getLabel());
1334 allocateGlobalReservedLeases6(ctx, existing_leases);
1349 for (
auto const& lease : existing_leases) {
1350 if ((lease->valid_lft_ != 0) &&
1356 .arg(ctx.query_->getLabel())
1357 .arg(lease->typeToText(lease->type_))
1358 .arg(lease->addr_.toText());
1364 if (!ghost->getHostname().empty()) {
1371 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1372 static_cast<bool>(fqdn));
1387 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1388 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1390 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1391 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1395 if (ctx.isAllocated(addr, prefix_len)) {
1407 bool valid_subnet =
false;
1408 auto subnet = ctx.subnet_;
1410 if (subnet->inRange(addr)) {
1411 valid_subnet =
true;
1415 subnet = subnet->getNextSubnet(ctx.subnet_);
1418 if (!valid_subnet) {
1421 .arg(ctx.query_->getLabel())
1427 ctx.subnet_ = subnet;
1430 if (!ghost->getHostname().empty()) {
1444 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1445 static_cast<bool>(fqdn));
1450 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1457 existing_leases.push_back(lease);
1462 .arg(ctx.query_->getLabel());
1466 .arg(
static_cast<int>(prefix_len))
1467 .arg(ctx.query_->getLabel());
1485AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1488 if (existing_leases.empty() || !ctx.subnet_) {
1493 if (!ctx.subnet_->getReservationsInSubnet() &&
1494 !ctx.subnet_->getReservationsGlobal()) {
1495 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1504 for (
auto const& candidate :
copy) {
1508 if ((ctx.hasGlobalReservation(resv)) ||
1509 ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
1510 (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1519 auto hosts = getIPv6Resrv(ctx.subnet_->getID(), candidate->addr_);
1524 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1525 candidate->addr_,
false)) {
1529 if (!hosts.empty()) {
1532 if (hosts.size() == 1) {
1535 .arg(ctx.query_->getLabel())
1536 .arg(candidate->addr_.
toText())
1537 .arg(ctx.duid_->toText())
1538 .arg(hosts.front()->getIdentifierAsText());
1541 .arg(ctx.query_->getLabel())
1542 .arg(candidate->addr_.
toText())
1543 .arg(
static_cast<int>(candidate->prefixlen_))
1544 .arg(ctx.duid_->toText())
1545 .arg(hosts.front()->getIdentifierAsText());
1550 .arg(ctx.query_->getLabel())
1551 .arg(candidate->addr_.
toText())
1552 .arg(ctx.duid_->toText())
1556 .arg(ctx.query_->getLabel())
1557 .arg(candidate->addr_.
toText())
1558 .arg(
static_cast<int>(candidate->prefixlen_))
1559 .arg(ctx.duid_->toText())
1578 "assigned-nas" :
"assigned-pds",
1579 static_cast<int64_t
>(-1));
1584 "assigned-nas" :
"assigned-pds"),
1585 static_cast<int64_t
>(-1));
1589 auto const& pool = subnet->getPool(ctx.currentIA().type_, candidate->addr_,
false);
1594 "pool" :
"pd-pool", pool->getID(),
1596 "assigned-nas" :
"assigned-pds")),
1597 static_cast<int64_t
>(-1));
1607 ctx.currentIA().old_leases_.push_back(candidate);
1610 removeLeases(existing_leases, candidate->addr_);
1615AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1622 for (
auto const& candidate :
copy) {
1626 if (inAllowedPool(ctx, candidate->type_,
1627 candidate->addr_,
false)) {
1643 "assigned-nas" :
"assigned-pds",
1644 static_cast<int64_t
>(-1));
1649 "assigned-nas" :
"assigned-pds"),
1650 static_cast<int64_t
>(-1));
1654 auto const& pool = subnet->getPool(candidate->type_, candidate->addr_,
false);
1659 "pool" :
"pd-pool", pool->getID(),
1661 "assigned-nas" :
"assigned-pds")),
1662 static_cast<int64_t
>(-1));
1667 ctx.currentIA().old_leases_.push_back(candidate);
1670 removeLeases(existing_leases, candidate->addr_);
1675AllocEngine::removeLeases(
Lease6Collection& container,
const asiolink::IOAddress& addr) {
1677 bool removed =
false;
1678 for (Lease6Collection::iterator lease = container.begin();
1679 lease != container.end(); ++lease) {
1680 if ((*lease)->addr_ == addr) {
1687 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1698 int total = existing_leases.size();
1705 for (Lease6Collection::iterator lease = existing_leases.begin();
1706 lease != existing_leases.end(); ++lease) {
1710 if (ctx.hasGlobalReservation(resv) ||
1711 ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
1712 (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1732 "assigned-nas" :
"assigned-pds",
1733 static_cast<int64_t
>(-1));
1738 "assigned-nas" :
"assigned-pds"),
1739 static_cast<int64_t
>(-1));
1743 auto const& pool = subnet->getPool(ctx.currentIA().type_, (*lease)->addr_,
false);
1748 "pool" :
"pd-pool", pool->getID(),
1750 "assigned-nas" :
"assigned-pds")),
1751 static_cast<int64_t
>(-1));
1758 ctx.currentIA().old_leases_.push_back(*lease);
1773 existing_leases.erase(std::remove(existing_leases.begin(),
1774 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1779useMinLifetimes6(AllocEngine::ClientContext6& ctx,
const IOAddress& addr,
1780 uint8_t prefix_len) {
1781 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
1782 if (!threshold.unspecified() && (threshold < 1.0)) {
1784 getOccupancyRate(addr, prefix_len, ctx.
query_->getClasses());
1785 if (occupancy >= threshold) {
1798 if (!expired->expired()) {
1799 isc_throw(BadValue,
"Attempt to recycle lease that is still valid");
1803 isc_throw(BadValue,
"Attempt to recycle registered address");
1810 if (!ctx.fake_allocation_) {
1814 reclaimExpiredLease(expired, ctx.callout_handle_);
1818 expired->iaid_ = ctx.currentIA().iaid_;
1819 expired->duid_ = ctx.duid_;
1820 expired->hwaddr_ = ctx.hwaddr_;
1823 expired->preferred_lft_ = 0;
1824 expired->valid_lft_ = 0;
1826 useMinLifetimes6(ctx, expired->addr_, prefix_len)) {
1829 getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
1831 expired->reuseable_valid_lft_ = 0;
1833 expired->cltt_ = time(0);
1834 expired->subnet_id_ = ctx.subnet_->getID();
1835 expired->hostname_ = ctx.hostname_;
1836 expired->fqdn_fwd_ = ctx.fwd_dns_update_;
1837 expired->fqdn_rev_ = ctx.rev_dns_update_;
1838 expired->prefixlen_ = prefix_len;
1843 .arg(ctx.query_->getLabel())
1844 .arg(expired->toText());
1847 if (ctx.callout_handle_ &&
1854 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
1857 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
1862 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1865 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1868 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1871 ctx.callout_handle_->setArgument(
"lease6", expired);
1876 callout_status = ctx.callout_handle_->getStatus();
1893 ctx.callout_handle_->getArgument(
"lease6", expired);
1896 if (!ctx.fake_allocation_) {
1900 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_,
false);
1902 expired->pool_id_ = pool->getID();
1910 if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
1914 "assigned-nas" :
"assigned-pds"),
1915 static_cast<int64_t
>(1));
1920 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
1921 static_cast<int64_t
>(1));
1927 "pool" :
"pd-pool", pool->getID(),
1929 "assigned-nas" :
"assigned-pds")),
1930 static_cast<int64_t
>(1));
1935 "pool" :
"pd-pool", pool->getID(),
1937 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
1938 static_cast<int64_t
>(1));
1942 "assigned-nas" :
"assigned-pds",
1943 static_cast<int64_t
>(1));
1946 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
1947 static_cast<int64_t
>(1));
1960void sanitizeLifetimes6(AllocEngine::ClientContext6& ctx,
1961 uint32_t& preferred, uint32_t& valid) {
1963 if (!preferred || preferred > valid) {
1964 preferred = ((valid * 5)/8);
1967 .arg(ctx.
query_->getLabel())
1980 if (!classes.
empty()) {
1987 for (
auto const& name : classes) {
1990 (cl && (!cl->getPreferred().unspecified()))) {
1991 candidate_preferred = cl->getPreferred();
1996 (cl && (!cl->getValid().unspecified()))) {
1997 candidate_valid = cl->getValid();
2000 if (have_both == 2) {
2007 if (!candidate_preferred) {
2008 candidate_preferred = ctx.
subnet_->getPreferred();
2012 if (!candidate_valid) {
2013 candidate_valid = ctx.
subnet_->getValid();
2017 preferred = candidate_preferred;
2018 valid = candidate_valid;
2032 sanitizeLifetimes6(ctx, preferred, valid);
2043 if (!classes.
empty()) {
2050 for (
auto const& name : classes) {
2053 (cl && (!cl->getPreferred().unspecified()))) {
2054 candidate_preferred = cl->getPreferred();
2059 (cl && (!cl->getValid().unspecified()))) {
2060 candidate_valid = cl->getValid();
2063 if (have_both == 2) {
2070 if (!candidate_preferred) {
2071 candidate_preferred = ctx.
subnet_->getPreferred();
2075 if (!candidate_valid) {
2076 candidate_valid = ctx.
subnet_->getValid();
2080 uint32_t remain_preferred(preferred);
2081 uint32_t remain_valid(valid);
2084 preferred = candidate_preferred.
getMin();
2085 valid = candidate_valid.
getMin();
2088 if (remain_preferred > preferred) {
2089 preferred = remain_preferred;
2091 if (remain_valid > valid) {
2092 valid = remain_valid;
2095 sanitizeLifetimes6(ctx, preferred, valid);
2107 uint32_t preferred = 0;
2110 useMinLifetimes6(ctx, addr, prefix_len)) {
2116 Lease6Ptr lease(
new Lease6(ctx.currentIA().type_, addr, ctx.duid_,
2117 ctx.currentIA().iaid_, preferred,
2118 valid, ctx.subnet_->getID(),
2119 ctx.hwaddr_, prefix_len));
2121 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2122 lease->fqdn_rev_ = ctx.rev_dns_update_;
2123 lease->hostname_ = ctx.hostname_;
2126 if (ctx.callout_handle_ &&
2133 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
2136 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2141 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
2144 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
2147 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
2150 ctx.callout_handle_->setArgument(
"lease6", lease);
2155 callout_status = ctx.callout_handle_->getStatus();
2167 ctx.callout_handle_->getArgument(
"lease6", lease);
2170 if (!ctx.fake_allocation_) {
2174 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2176 lease->pool_id_ = pool->getID();
2185 if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
2189 "assigned-nas" :
"assigned-pds"),
2190 static_cast<int64_t
>(1));
2195 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2196 static_cast<int64_t
>(1));
2202 "pool" :
"pd-pool", pool->getID(),
2204 "assigned-nas" :
"assigned-pds")),
2205 static_cast<int64_t
>(1));
2210 "pool" :
"pd-pool", pool->getID(),
2212 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2213 static_cast<int64_t
>(1));
2217 "assigned-nas" :
"assigned-pds",
2218 static_cast<int64_t
>(1));
2221 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2222 static_cast<int64_t
>(1));
2226 ctx.currentIA().addNewResource(addr, prefix_len);
2253 time_t now = time(0);
2255 if (lease->cltt_ > now) {
2258 uint32_t age = now - lease->cltt_;
2260 if (age >= lease->valid_lft_) {
2263 valid = lease->valid_lft_ - age;
2264 if (age >= lease->preferred_lft_) {
2267 preferred = lease->preferred_lft_ - age;
2290 for (
auto const& l : leases_subnet) {
2292 leases.push_back(l);
2295 subnet = subnet->getNextSubnet(ctx.
subnet_);
2298 if (!leases.empty()) {
2301 .arg(ctx.
query_->getLabel());
2305 removeNonmatchingReservedLeases6(ctx, leases);
2308 if (!ctx.
hosts_.empty()) {
2312 .arg(ctx.
query_->getLabel());
2315 allocateReservedLeases6(ctx, leases);
2321 removeNonreservedLeases6(ctx, leases);
2328 if (leases.empty()) {
2332 .arg(ctx.
query_->getLabel());
2334 leases = allocateUnreservedLeases6(ctx);
2338 for (
auto const& l : leases) {
2346 .arg(ctx.
query_->getLabel())
2347 .arg(l->typeToText(l->type_))
2349 extendLease6(ctx, l);
2352 if (!leases.empty()) {
2356 for (
auto const& lease : leases) {
2371 .arg(ctx.
query_->getLabel())
2381 if (!lease || !ctx.subnet_) {
2387 if (ctx.subnet_->getID() != lease->subnet_id_) {
2389 ctx.subnet_->getSharedNetwork(network);
2392 network->getSubnet(
SubnetID(lease->subnet_id_));
2396 ctx.subnet_ = subnet;
2404 (((lease->type_ !=
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
2405 !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
2420 "assigned-nas" :
"assigned-pds",
static_cast<int64_t
>(-1));
2425 "assigned-nas" :
"assigned-pds"),
2426 static_cast<int64_t
>(-1));
2428 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2433 "pool" :
"pd-pool", pool->getID(),
2435 "assigned-nas" :
"assigned-pds")),
2436 static_cast<int64_t
>(-1));
2440 ctx.currentIA().old_leases_.push_back(lease);
2447 .arg(ctx.query_->getLabel())
2448 .arg(lease->toText());
2453 bool changed =
false;
2456 uint32_t current_preferred_lft = lease->preferred_lft_;
2458 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2459 uint32_t remain_preferred_lft(0);
2460 uint32_t remain_valid_lft(0);
2461 getRemaining(lease, remain_preferred_lft, remain_valid_lft);
2462 lease->preferred_lft_ = remain_preferred_lft;
2463 lease->valid_lft_ = remain_valid_lft;
2466 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2470 if ((lease->preferred_lft_ != current_preferred_lft) ||
2471 (lease->valid_lft_ != lease->current_valid_lft_)) {
2475 lease->cltt_ = time(NULL);
2476 if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
2477 (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
2478 (lease->hostname_ != ctx.hostname_)) {
2480 lease->hostname_ = ctx.hostname_;
2481 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2482 lease->fqdn_rev_ = ctx.rev_dns_update_;
2484 if ((!ctx.hwaddr_ && lease->hwaddr_) ||
2486 (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
2488 lease->hwaddr_ = ctx.hwaddr_;
2496 .arg(ctx.query_->getLabel())
2497 .arg(lease->toText());
2501 int hook_point = ctx.query_->getType() ==
DHCPV6_RENEW ?
2502 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2510 ScopedCalloutHandleState callout_handle_state(callout_handle);
2513 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2516 callout_handle->setArgument(
"query6", ctx.query_);
2519 callout_handle->setArgument(
"lease6", lease);
2523 callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
2525 callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
2538 .arg(ctx.query_->getName());
2545 bool update_stats =
false;
2549 if (old_data->expired()) {
2550 reclaimExpiredLease(old_data, ctx.callout_handle_);
2554 if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
2555 update_stats =
true;
2568 setLeaseReusable(lease, current_preferred_lft, ctx);
2573 if (lease->reuseable_valid_lft_ == 0) {
2574 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2576 lease->pool_id_ = pool->getID();
2582 old_data->reuseable_valid_lft_ = lease->reuseable_valid_lft_;
2589 "assigned-nas" :
"assigned-pds"),
2590 static_cast<int64_t
>(1));
2595 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2596 static_cast<int64_t
>(1));
2598 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2603 "pool" :
"pd-pool", pool->getID(),
2605 "assigned-nas" :
"assigned-pds")),
2606 static_cast<int64_t
>(1));
2611 "pool" :
"pd-pool", pool->getID(),
2613 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2614 static_cast<int64_t
>(1));
2618 "assigned-nas" :
"assigned-pds",
2619 static_cast<int64_t
>(1));
2623 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2624 static_cast<int64_t
>(1));
2637 ctx.currentIA().changed_leases_.push_back(old_data);
2643 for (
auto const& lease_it : leases) {
2645 if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
2647 updated_leases.push_back(lease);
2651 lease->reuseable_valid_lft_ = 0;
2652 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2653 lease->fqdn_rev_ = ctx.rev_dns_update_;
2654 lease->hostname_ = ctx.hostname_;
2655 uint32_t current_preferred_lft = lease->preferred_lft_;
2656 if (lease->valid_lft_ == 0) {
2658 lease->preferred_lft_ = 0;
2660 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2663 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2666 if (!ctx.fake_allocation_) {
2667 bool update_stats =
false;
2675 if (inAllowedPool(ctx, ctx.currentIA().type_,
2676 lease->addr_,
true)) {
2677 update_stats =
true;
2682 !(lease->hasIdenticalFqdn(*lease_it)));
2684 lease->cltt_ = time(NULL);
2685 if (!fqdn_changed) {
2686 setLeaseReusable(lease, current_preferred_lft, ctx);
2689 if (lease->reuseable_valid_lft_ == 0) {
2690 ctx.currentIA().changed_leases_.push_back(lease_it);
2694 ctx.currentIA().reused_leases_.push_back(lease_it);
2701 "assigned-nas" :
"assigned-pds"),
2702 static_cast<int64_t
>(1));
2707 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2708 static_cast<int64_t
>(1));
2710 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2715 "pool" :
"pd-pool", pool->getID(),
2717 "assigned-nas" :
"assigned-pds")),
2718 static_cast<int64_t
>(1));
2723 "pool" :
"pd-pool", pool->getID(),
2725 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2726 static_cast<int64_t
>(1));
2730 "assigned-nas" :
"assigned-pds",
2731 static_cast<int64_t
>(1));
2734 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2735 static_cast<int64_t
>(1));
2739 updated_leases.push_back(lease);
2742 return (updated_leases);
2747 const uint16_t timeout,
2748 const bool remove_lease,
2749 const uint16_t max_unwarned_cycles) {
2758 max_unwarned_cycles);
2759 }
catch (
const std::exception& ex) {
2768 const uint16_t timeout,
2769 const bool remove_lease,
2770 const uint16_t max_unwarned_cycles) {
2780 bool incomplete_reclamation =
false;
2783 if (max_leases > 0) {
2792 if (leases.size() > max_leases) {
2794 incomplete_reclamation =
true;
2807 if (!leases.empty() &&
2812 size_t leases_processed = 0;
2813 for (
auto const& lease : leases) {
2821 reclaimExpiredLease(lease, remove_lease, callout_handle);
2824 reclaimExpiredLease(lease, remove_lease, callout_handle);
2828 }
catch (
const std::exception& ex) {
2830 .arg(lease->addr_.toText())
2841 if (!incomplete_reclamation) {
2842 if (leases_processed < leases.size()) {
2843 incomplete_reclamation =
true;
2860 .arg(leases_processed)
2865 if (incomplete_reclamation) {
2866 ++incomplete_v6_reclamations_;
2869 if ((max_unwarned_cycles > 0) &&
2870 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2872 .arg(max_unwarned_cycles);
2874 incomplete_v6_reclamations_ = 0;
2879 incomplete_v6_reclamations_ = 0;
2892 uint64_t deleted_leases = 0;
2898 }
catch (
const std::exception& ex) {
2905 .arg(deleted_leases);
2910 const uint16_t timeout,
2911 const bool remove_lease,
2912 const uint16_t max_unwarned_cycles) {
2921 max_unwarned_cycles);
2922 }
catch (
const std::exception& ex) {
2931 const uint16_t timeout,
2932 const bool remove_lease,
2933 const uint16_t max_unwarned_cycles) {
2943 bool incomplete_reclamation =
false;
2946 if (max_leases > 0) {
2955 if (leases.size() > max_leases) {
2957 incomplete_reclamation =
true;
2970 if (!leases.empty() &&
2975 size_t leases_processed = 0;
2976 for (
auto const& lease : leases) {
2984 reclaimExpiredLease(lease, remove_lease, callout_handle);
2987 reclaimExpiredLease(lease, remove_lease, callout_handle);
2991 }
catch (
const std::exception& ex) {
2993 .arg(lease->addr_.toText())
3004 if (!incomplete_reclamation) {
3005 if (leases_processed < leases.size()) {
3006 incomplete_reclamation =
true;
3023 .arg(leases_processed)
3028 if (incomplete_reclamation) {
3029 ++incomplete_v4_reclamations_;
3032 if ((max_unwarned_cycles > 0) &&
3033 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
3035 .arg(max_unwarned_cycles);
3037 incomplete_v4_reclamations_ = 0;
3042 incomplete_v4_reclamations_ = 0;
3049template<
typename LeasePtrType>
3051AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
3053 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
3057template<
typename LeasePtrType>
3059AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
3064 if (!lease->stateExpiredReclaimed()) {
3065 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
3070AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
3071 const DbReclaimMode& reclaim_mode,
3077 .arg(lease->addr_.toText())
3078 .arg(
static_cast<int>(lease->prefixlen_));
3084 bool skipped =
false;
3087 if (callout_handle) {
3093 ScopedCalloutHandleState callout_handle_state(callout_handle);
3095 callout_handle->deleteAllArguments();
3096 callout_handle->setArgument(
"lease6", lease);
3097 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3117 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3127 remove_lease = reclaimDeclined(lease);
3129 if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
3130 isc_throw(Unexpected,
"attempt to reuse a registered lease");
3133 remove_lease =
true;
3136 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3140 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
3142 &lease_mgr, ph::_1));
3154 "reclaimed-leases"),
3155 static_cast<int64_t
>(1));
3161 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3167 pool->getID(),
"reclaimed-leases")),
3168 static_cast<int64_t
>(1));
3184 static_cast<int64_t
>(-1));
3188 "assigned-nas" :
"assigned-pds",
3189 static_cast<int64_t
>(-1));
3194 "assigned-nas" :
"assigned-pds"),
3195 static_cast<int64_t
>(-1));
3198 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3203 "pool" :
"pd-pool", pool->getID(),
3205 "assigned-nas" :
"assigned-pds")),
3206 static_cast<int64_t
>(-1));
3213AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
3214 const DbReclaimMode& reclaim_mode,
3220 .arg(lease->addr_.toText());
3226 bool skipped =
false;
3228 if (callout_handle) {
3234 ScopedCalloutHandleState callout_handle_state(callout_handle);
3236 callout_handle->setArgument(
"lease4", lease);
3237 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3255 lease->hostname_.clear();
3256 lease->fqdn_fwd_ =
false;
3257 lease->fqdn_rev_ =
false;
3261 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3271 remove_lease = reclaimDeclined(lease);
3274 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3278 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
3280 &lease_mgr, ph::_1));
3292 "reclaimed-leases"),
3293 static_cast<int64_t
>(1));
3298 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3303 "reclaimed-leases")),
3304 static_cast<int64_t
>(1));
3318 "assigned-addresses"),
3319 static_cast<int64_t
>(-1));
3322 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3327 "assigned-addresses")),
3328 static_cast<int64_t
>(-1));
3339 uint64_t deleted_leases = 0;
3345 }
catch (
const std::exception& ex) {
3352 .arg(deleted_leases);
3356AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3371 callout_handle->setArgument(
"lease4", lease);
3381 .arg(lease->addr_.toText());
3387 .arg(lease->addr_.toText())
3388 .arg(lease->valid_lft_);
3394 "declined-addresses"),
3395 static_cast<int64_t
>(-1));
3398 "reclaimed-declined-addresses"),
3399 static_cast<int64_t
>(1));
3403 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3407 "declined-addresses")),
3408 static_cast<int64_t
>(-1));
3412 "reclaimed-declined-addresses")),
3413 static_cast<int64_t
>(1));
3418 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3420 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3428AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3440 ScopedCalloutHandleState callout_handle_state(callout_handle);
3443 callout_handle->setArgument(
"lease6", lease);
3453 .arg(lease->addr_.toText());
3459 .arg(lease->addr_.toText())
3460 .arg(lease->valid_lft_);
3466 "declined-addresses"),
3467 static_cast<int64_t
>(-1));
3470 "reclaimed-declined-addresses"),
3471 static_cast<int64_t
>(1));
3475 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3479 "declined-addresses")),
3480 static_cast<int64_t
>(-1));
3484 "reclaimed-declined-addresses")),
3485 static_cast<int64_t
>(1));
3490 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3492 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3501 lease->relay_id_.clear();
3502 lease->remote_id_.clear();
3503 if (lease->getContext()) {
3510 if (lease->getContext()) {
3516template<
typename LeasePtrType>
3517void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3518 const bool remove_lease,
3519 const std::function<
void (
const LeasePtrType&)>&
3520 lease_update_fun)
const {
3528 }
else if (lease_update_fun) {
3531 lease->reuseable_valid_lft_ = 0;
3532 lease->hostname_.clear();
3533 lease->fqdn_fwd_ =
false;
3534 lease->fqdn_rev_ =
false;
3537 lease_update_fun(lease);
3546 .arg(lease->addr_.toText());
3552 return(
"<empty subnet>");
3556 subnet->getSharedNetwork(network);
3557 std::ostringstream ss;
3559 ss <<
"shared-network: " << network->getName();
3561 ss <<
"subnet id: " << subnet->getID();
3600 (!ctx.
subnet_->getReservationsOutOfPool() ||
3611 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
3616 hosts.push_back(host);
3630 for (
auto const& host : hosts) {
3634 if (id_pair.first == host->getIdentifierType() &&
3635 id_pair.second == host->getIdentifier()) {
3643 return (!hosts.empty());
3665 if (ctx.
hosts_.empty()) {
3670 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3671 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3672 global_host->second->getIPv4Reservation() :
3681 if (subnet->getReservationsGlobal() &&
3683 (subnet->inRange(global_host_address))) {
3688 if (subnet->getReservationsInSubnet()) {
3689 auto host = ctx.
hosts_.find(subnet->getID());
3694 if (host != ctx.
hosts_.end() && host->second) {
3695 auto reservation = host->second->getIPv4Reservation();
3696 if (!reservation.isV4Zero() &&
3697 (!subnet->getReservationsOutOfPool() ||
3707 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3713 .arg(ctx.
query_->getLabel())
3714 .arg(global_host_address.toText())
3741 auto const& classes = ctx.
query_->getClasses();
3745 bool try_clientid_lookup = (ctx.
clientid_ &&
3749 if (try_clientid_lookup) {
3758 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3763 if (subnet->getMatchClientId()) {
3764 for (
auto const& l : leases_client_id) {
3765 if (l->subnet_id_ == subnet->getID()) {
3778 if (!client_lease && ctx.
hwaddr_) {
3784 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3786 if (subnet->getMatchClientId()) {
3792 for (
auto const& client_lease_it : leases_hw_address) {
3793 Lease4Ptr existing_lease = client_lease_it;
3794 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3795 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3797 client_lease = existing_lease;
3825 auto const& classes = ctx.
query_->getClasses();
3827 while (current_subnet) {
3836 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3863 const bool fwd_dns_update,
3864 const bool rev_dns_update,
3865 const std::string& hostname,
3866 const bool fake_allocation,
3867 const uint32_t offer_lft)
3887 if (host !=
hosts_.cend()) {
3888 return (host->second);
3898 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3899 if (host !=
hosts_.cend()) {
3900 return (host->second);
3910 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3911 return (ddns_params_);
3917 return (ddns_params_);
3939 auto const& classes = ctx.
query_->getClasses();
3940 if (subnet && !subnet->clientSupported(classes)) {
3941 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
3965 .arg(ctx.
query_->getLabel())
3983 !subnet->getReservationsInSubnet()) {
3989 subnet->getReservationsGlobal()) {
3992 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3995 if (!subnet->getReservationsInSubnet()) {
4001 std::map<SubnetID, ConstHostPtr> host_map;
4003 subnet->getSharedNetwork(network);
4012 const bool use_single_query = network &&
4016 if (use_single_query) {
4020 id_pair.second.size());
4024 for (
auto const& host : hosts) {
4025 if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
4026 host_map[host->getIPv4SubnetID()] = host;
4032 auto const& classes = ctx.
query_->getClasses();
4038 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
4041 if (use_single_query) {
4042 if (host_map.count(subnet->getID()) > 0) {
4043 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
4051 id_pair.second.size());
4054 ctx.
hosts_[subnet->getID()] = host;
4064 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
4070 for (
auto const& host : ctx.
hosts_) {
4071 host.second->encapsulateOptions();
4081 &id_pair.second[0], id_pair.second.size());
4098 findClientLease(ctx, client_lease);
4111 if (hasAddressReservation(ctx)) {
4115 .arg(ctx.
query_->getLabel())
4116 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
4122 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
4129 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
4133 .arg(ctx.
query_->getLabel())
4134 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4140 "v4-reservation-conflicts"),
4141 static_cast<int64_t
>(1));
4143 static_cast<int64_t
>(1));
4148 new_lease = renewLease4(client_lease, ctx);
4161 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
4162 !addressReserved(client_lease->addr_, ctx)) {
4166 .arg(ctx.
query_->getLabel());
4172 (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
4176 new_lease = renewLease4(client_lease, ctx);
4193 .arg(ctx.
query_->getLabel());
4206 .arg(ctx.
query_->getLabel());
4208 new_lease = allocateUnreservedLease4(ctx);
4229 "assigned-addresses"),
4230 static_cast<int64_t
>(-1));
4233 ->getBySubnetId(lease->subnet_id_);
4235 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4239 "assigned-addresses")),
4240 static_cast<int64_t
>(-1));
4252 findClientLease(ctx, client_lease);
4268 .arg(ctx.
query_->getLabel())
4274 }
else if (hasAddressReservation(ctx)) {
4283 .arg(ctx.
query_->getLabel())
4295 if (existing && !existing->expired() &&
4296 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4301 .arg(ctx.
query_->getLabel())
4311 if (hasAddressReservation(ctx) &&
4319 if (!existing || existing->expired()) {
4323 .arg(ctx.
query_->getLabel())
4324 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4334 if ((!hasAddressReservation(ctx) ||
4340 .arg(ctx.
query_->getLabel())
4352 if (((client_lease && existing) && (client_lease->addr_ != existing->addr_) &&
4354 (existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4357 auto conflicted_lease = client_lease;
4358 client_lease = existing;
4375 ((hasAddressReservation(ctx) &&
4377 inAllowedPool(ctx, client_lease->addr_))) {
4381 .arg(ctx.
query_->getLabel())
4383 return (renewLease4(client_lease, ctx));
4397 .arg(ctx.
query_->getLabel())
4412 .arg(ctx.
query_->getLabel());
4417 new_lease = allocateUnreservedLease4(ctx);
4423 if (new_lease && client_lease) {
4428 .arg(ctx.
query_->getLabel())
4429 .arg(client_lease->addr_.toText());
4450 if (!classes.
empty()) {
4456 for (
auto const& name : classes) {
4458 if (cl && (!cl->getOfferLft().unspecified())) {
4459 offer_lft = cl->getOfferLft();
4467 offer_lft = ctx.
subnet_->getOfferLft();
4476 if (ctx.
query_->inClass(
"BOOTP")) {
4481 uint32_t requested_lft = 0;
4484 OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
4486 requested_lft = opt_lft->getValue();
4494 if (!classes.
empty()) {
4500 for (
auto const& name : classes) {
4502 if (cl && (!cl->getValid().unspecified())) {
4503 candidate_lft = cl->getValid();
4510 if (!candidate_lft) {
4511 candidate_lft = ctx.
subnet_->getValid();
4516 if (requested_lft > 0) {
4517 return (candidate_lft.
get(requested_lft));
4521 return (candidate_lft.
get());
4527 if (ctx.
query_->inClass(
"BOOTP")) {
4536 if (!classes.
empty()) {
4542 for (
auto const& name : classes) {
4544 if (cl && (!cl->getValid().unspecified())) {
4545 candidate_lft = cl->getValid();
4552 if (!candidate_lft) {
4553 candidate_lft = ctx.
subnet_->getValid();
4557 uint32_t remain(valid);
4560 valid = candidate_lft.
getMin();
4563 if (remain > valid) {
4571 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
4572 if (!threshold.unspecified() && (threshold < 1.0)) {
4574 getOccupancyRate(addr, ctx.
query_->getClasses());
4575 if (occupancy >= threshold) {
4584AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
4587 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
4590 isc_throw(BadValue,
"Can't create a lease without a subnet");
4594 uint32_t valid_lft = ctx.offer_lft_;
4596 if (useMinValidLft(ctx, addr)) {
4603 time_t now = time(0);
4606 if (ctx.subnet_->getMatchClientId()) {
4607 client_id = ctx.clientid_;
4610 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
4611 valid_lft, now, ctx.subnet_->getID()));
4614 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
4615 lease->fqdn_rev_ = ctx.rev_dns_update_;
4616 lease->hostname_ = ctx.hostname_;
4622 if (ctx.callout_handle_ &&
4629 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
4632 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
4636 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
4643 boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
4644 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
4647 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
4650 ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
4653 ctx.callout_handle_->setArgument(
"lease4", lease);
4658 callout_status = ctx.callout_handle_->getStatus();
4670 ctx.callout_handle_->getArgument(
"lease4", lease);
4673 if (ctx.fake_allocation_ && ctx.offer_lft_) {
4677 lease->fqdn_fwd_ =
false;
4678 lease->fqdn_rev_ =
false;
4681 if (!ctx.fake_allocation_ || ctx.offer_lft_) {
4682 auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4684 lease->pool_id_ = pool->getID();
4693 "assigned-addresses"),
4694 static_cast<int64_t
>(1));
4698 "cumulative-assigned-addresses"),
4699 static_cast<int64_t
>(1));
4705 "assigned-addresses")),
4706 static_cast<int64_t
>(1));
4711 "cumulative-assigned-addresses")),
4712 static_cast<int64_t
>(1));
4747 time_t now = time(0);
4749 if (lease->cltt_ > now) {
4752 uint32_t age = now - lease->cltt_;
4754 if (age >= lease->valid_lft_) {
4757 valid = lease->valid_lft_ - age;
4761AllocEngine::renewLease4(
const Lease4Ptr& lease,
4771 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4776 lease->reuseable_valid_lft_ = 0;
4777 if (!updateLease4Information(lease, ctx)) {
4778 setLeaseReusable(lease, ctx);
4803 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4810 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4819 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4845 lease->pool_id_ = pool->getID();
4855 "assigned-addresses"),
4856 static_cast<int64_t
>(1));
4860 "cumulative-assigned-addresses"),
4861 static_cast<int64_t
>(1));
4867 "assigned-addresses")),
4868 static_cast<int64_t
>(1));
4873 "cumulative-assigned-addresses")),
4874 static_cast<int64_t
>(1));
4885 *lease = *old_values;
4892AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4893 AllocEngine::ClientContext4& ctx,
4896 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
4900 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
4911 expired->reuseable_valid_lft_ = 0;
4912 static_cast<void>(updateLease4Information(expired, ctx));
4916 .arg(ctx.
query_->getLabel())
4917 .arg(expired->toText());
4924 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4941 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4975 expired->pool_id_ = pool->getID();
4983 "assigned-addresses"),
4984 static_cast<int64_t
>(1));
4988 "cumulative-assigned-addresses"),
4989 static_cast<int64_t
>(1));
4995 "assigned-addresses")),
4996 static_cast<int64_t
>(1));
5001 "cumulative-assigned-addresses")),
5002 static_cast<int64_t
>(1));
5019AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate,
ClientContext4& ctx,
5021 ctx.conflicting_lease_.reset();
5025 if (exist_lease->expired()) {
5026 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5030 ctx.old_lease_->hostname_.clear();
5031 ctx.old_lease_->fqdn_fwd_ =
false;
5032 ctx.old_lease_->fqdn_rev_ =
false;
5033 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
5039 ctx.conflicting_lease_ = exist_lease;
5043 return (createLease4(ctx, candidate, callout_status));
5063 ctx.subnet_->getSharedNetwork(network);
5070 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
5084 uint64_t subnets_with_unavail_leases = 0;
5087 uint64_t subnets_with_unavail_pools = 0;
5089 auto const& classes = ctx.query_->getClasses();
5093 if (subnet->getMatchClientId()) {
5094 client_id = ctx.clientid_;
5106 (attempts_ == 0 || possible_attempts < attempts_) ?
5110 if (max_attempts > 0) {
5113 ++subnets_with_unavail_leases;
5117 ++subnets_with_unavail_pools;
5120 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
5125 for (
uint128_t i = 0; i < max_attempts; ++i) {
5130 IOAddress candidate = allocator->pickAddress(classes,
5132 ctx.requested_address_);
5139 if (exclude_first_last_24) {
5141 auto const& bytes = candidate.
toBytes();
5142 if ((bytes.size() != 4) ||
5143 (bytes[3] == 0) || (bytes[3] == 255U)) {
5150 if (check_reservation_first && addressReserved(candidate, ctx)) {
5157 ResourceHandler4 resource_handler;
5159 !resource_handler.
tryLock4(candidate)) {
5168 if (check_reservation_first || !addressReserved(candidate, ctx)) {
5170 new_lease = createLease4(ctx, candidate, callout_status);
5174 if (exist_lease->expired() &&
5175 (check_reservation_first || !addressReserved(candidate, ctx))) {
5176 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5177 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
5195 subnet = subnet->getNextSubnet(original_subnet, classes);
5198 ctx.subnet_ = subnet;
5207 .arg(ctx.query_->getLabel())
5208 .arg(network->getName())
5209 .arg(subnets_with_unavail_leases)
5210 .arg(subnets_with_unavail_pools);
5212 static_cast<int64_t
>(1));
5215 "v4-allocation-fail-shared-network"),
5216 static_cast<int64_t
>(1));
5220 std::string shared_network = ctx.subnet_->getSharedNetworkName();
5221 if (shared_network.empty()) {
5222 shared_network =
"(none)";
5225 .arg(ctx.query_->getLabel())
5226 .arg(ctx.subnet_->toText())
5227 .arg(ctx.subnet_->getID())
5228 .arg(shared_network);
5230 static_cast<int64_t
>(1));
5233 "v4-allocation-fail-subnet"),
5234 static_cast<int64_t
>(1));
5236 if (total_attempts == 0) {
5242 .arg(ctx.query_->getLabel());
5244 static_cast<int64_t
>(1));
5247 "v4-allocation-fail-no-pools"),
5248 static_cast<int64_t
>(1));
5255 .arg(ctx.query_->getLabel())
5256 .arg(total_attempts);
5258 static_cast<int64_t
>(1));
5261 "v4-allocation-fail"),
5262 static_cast<int64_t
>(1));
5265 if (!classes.empty()) {
5267 .arg(ctx.query_->getLabel())
5268 .arg(classes.toText());
5270 static_cast<int64_t
>(1));
5273 "v4-allocation-fail-classes"),
5274 static_cast<int64_t
>(1));
5281AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
5282 AllocEngine::ClientContext4& ctx)
const {
5283 bool changed =
false;
5284 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
5286 lease->subnet_id_ = ctx.
subnet_->getID();
5288 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
5290 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
5295 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
5299 }
else if (lease->client_id_) {
5303 uint32_t remain_lft(0);
5305 lease->cltt_ = time(0);
5309 if (!lease->valid_lft_) {
5310 if (useMinValidLft(ctx, lease->addr_)) {
5311 lease->valid_lft_ = remain_lft;
5319 if (lease->valid_lft_ != lease->current_valid_lft_) {
5343 bool changed =
false;
5346 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5361 sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
5370 extended_info->set(
"sub-options", relay_agent);
5374 std::vector<uint8_t> bytes = remote_id->toBinary();
5375 lease->remote_id_ = bytes;
5376 if (bytes.size() > 0) {
5377 extended_info->set(
"remote-id",
5384 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5385 lease->relay_id_ = bytes;
5386 if (bytes.size() > 0) {
5387 extended_info->set(
"relay-id",
5393 return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
5403 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5408 if (ctx.
query_->relay_info_.empty()) {
5423 for (
auto const& relay : ctx.
query_->relay_info_) {
5432 if (!relay.options_.empty()) {
5437 const uint8_t* cp = buf.
getData();
5438 std::vector<uint8_t> bytes;
5439 std::stringstream ss;
5447 if (remote_id_it != relay.options_.end()) {
5448 OptionPtr remote_id = remote_id_it->second;
5450 std::vector<uint8_t> bytes = remote_id->toBinary();
5451 if (bytes.size() > 0) {
5452 relay_elem->set(
"remote-id",
5459 if (relay_id_it != relay.options_.end()) {
5460 OptionPtr relay_id = relay_id_it->second;
5462 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5463 if (bytes.size() > 0) {
5464 relay_elem->set(
"relay-id",
5471 extended_info->add(relay_elem);
5475 if (lease->updateUserContextISC(
"relay-info", extended_info)) {
5481AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
5482 const ClientContext4& ctx)
const {
5484 lease->reuseable_valid_lft_ = 0;
5500 if (lease->cltt_ < lease->current_cltt_) {
5504 uint32_t age = lease->cltt_ - lease->current_cltt_;
5506 if (age >= lease->current_valid_lft_) {
5511 uint32_t max_age = 0;
5512 if (!subnet->getCacheMaxAge().unspecified()) {
5513 max_age = subnet->getCacheMaxAge().get();
5514 if ((max_age == 0) || (age > max_age)) {
5520 if (!subnet->getCacheThreshold().unspecified()) {
5521 double threshold = subnet->getCacheThreshold().get();
5522 if ((threshold <= 0.) || (threshold > 1.)) {
5525 max_age = lease->valid_lft_ * threshold;
5526 if (age > max_age) {
5537 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
5541AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
5542 uint32_t current_preferred_lft,
5545 lease->reuseable_valid_lft_ = 0;
5546 lease->reuseable_preferred_lft_ = 0;
5556 if (lease->cltt_ < lease->current_cltt_) {
5560 uint32_t age = lease->cltt_ - lease->current_cltt_;
5562 if (age >= lease->current_valid_lft_) {
5567 uint32_t max_age = 0;
5568 if (!subnet->getCacheMaxAge().unspecified()) {
5569 max_age = subnet->getCacheMaxAge().get();
5570 if ((max_age == 0) || (age > max_age)) {
5576 if (!subnet->getCacheThreshold().unspecified()) {
5577 double threshold = subnet->getCacheThreshold().get();
5578 if ((threshold <= 0.) || (threshold > 1.)) {
5581 max_age = lease->valid_lft_ * threshold;
5582 if (age > max_age) {
5594 (current_preferred_lft == 0)) {
5596 lease->reuseable_preferred_lft_ = current_preferred_lft;
5597 }
else if (current_preferred_lft > age) {
5598 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
5606 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.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
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