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();
1243 if (in_subnet && !host->hasIPv6Reservation()) {
1244 ctx.subnet_ = subnet;
1245 ctx.host_subnet_ = subnet;
1246 if (!host->getHostname().empty()) {
1249 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1250 static_cast<bool>(fqdn));
1258 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1260 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1261 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1265 if (ctx.isAllocated(addr, prefix_len)) {
1274 (subnet->getReservationsOutOfPool() &&
1275 subnet->inPool(ctx.currentIA().type_, addr))) {
1287 ctx.subnet_ = subnet;
1289 if (!ctx.host_subnet_) {
1290 ctx.host_subnet_ = subnet;
1291 if (!host->getHostname().empty()) {
1305 qualifyName(host->getHostname(), *ctx.getDdnsParams(),
1306 static_cast<bool>(fqdn));
1312 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1319 existing_leases.push_back(lease);
1324 .arg(ctx.query_->getLabel());
1328 .arg(
static_cast<int>(prefix_len))
1329 .arg(ctx.query_->getLabel());
1347 allocateGlobalReservedLeases6(ctx, existing_leases);
1362 for (
auto const& lease : existing_leases) {
1363 if ((lease->valid_lft_ != 0) &&
1369 .arg(ctx.query_->getLabel())
1370 .arg(lease->typeToText(lease->type_))
1371 .arg(lease->addr_.toText());
1377 if (!ghost->getHostname().empty()) {
1384 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1385 static_cast<bool>(fqdn));
1400 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1401 BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
1403 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1404 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1408 if (ctx.isAllocated(addr, prefix_len)) {
1420 bool valid_subnet =
false;
1421 auto subnet = ctx.subnet_;
1423 if (subnet->inRange(addr)) {
1424 valid_subnet =
true;
1428 subnet = subnet->getNextSubnet(ctx.subnet_);
1431 if (!valid_subnet) {
1434 .arg(ctx.query_->getLabel())
1440 ctx.subnet_ = subnet;
1443 if (!ghost->getHostname().empty()) {
1457 qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
1458 static_cast<bool>(fqdn));
1463 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1470 existing_leases.push_back(lease);
1475 .arg(ctx.query_->getLabel());
1479 .arg(
static_cast<int>(prefix_len))
1480 .arg(ctx.query_->getLabel());
1498AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1501 if (existing_leases.empty() || !ctx.subnet_) {
1506 if (!ctx.subnet_->getReservationsInSubnet() &&
1507 !ctx.subnet_->getReservationsGlobal()) {
1508 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1517 for (
auto const& candidate :
copy) {
1521 if ((ctx.hasGlobalReservation(resv)) ||
1522 ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
1523 (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1532 auto hosts = getIPv6Resrv(ctx.subnet_->getID(), candidate->addr_);
1537 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1538 candidate->addr_,
false)) {
1542 if (!hosts.empty()) {
1545 if (hosts.size() == 1) {
1548 .arg(ctx.query_->getLabel())
1549 .arg(candidate->addr_.
toText())
1550 .arg(ctx.duid_->toText())
1551 .arg(hosts.front()->getIdentifierAsText());
1554 .arg(ctx.query_->getLabel())
1555 .arg(candidate->addr_.
toText())
1556 .arg(
static_cast<int>(candidate->prefixlen_))
1557 .arg(ctx.duid_->toText())
1558 .arg(hosts.front()->getIdentifierAsText());
1563 .arg(ctx.query_->getLabel())
1564 .arg(candidate->addr_.
toText())
1565 .arg(ctx.duid_->toText())
1569 .arg(ctx.query_->getLabel())
1570 .arg(candidate->addr_.
toText())
1571 .arg(
static_cast<int>(candidate->prefixlen_))
1572 .arg(ctx.duid_->toText())
1591 "assigned-nas" :
"assigned-pds",
1592 static_cast<int64_t
>(-1));
1597 "assigned-nas" :
"assigned-pds"),
1598 static_cast<int64_t
>(-1));
1602 auto const& pool = subnet->getPool(ctx.currentIA().type_, candidate->addr_,
false);
1607 "pool" :
"pd-pool", pool->getID(),
1609 "assigned-nas" :
"assigned-pds")),
1610 static_cast<int64_t
>(-1));
1620 ctx.currentIA().old_leases_.push_back(candidate);
1623 removeLeases(existing_leases, candidate->addr_);
1628AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1635 for (
auto const& candidate :
copy) {
1639 if (inAllowedPool(ctx, candidate->type_,
1640 candidate->addr_,
false)) {
1656 "assigned-nas" :
"assigned-pds",
1657 static_cast<int64_t
>(-1));
1662 "assigned-nas" :
"assigned-pds"),
1663 static_cast<int64_t
>(-1));
1667 auto const& pool = subnet->getPool(candidate->type_, candidate->addr_,
false);
1672 "pool" :
"pd-pool", pool->getID(),
1674 "assigned-nas" :
"assigned-pds")),
1675 static_cast<int64_t
>(-1));
1680 ctx.currentIA().old_leases_.push_back(candidate);
1683 removeLeases(existing_leases, candidate->addr_);
1688AllocEngine::removeLeases(
Lease6Collection& container,
const asiolink::IOAddress& addr) {
1690 bool removed =
false;
1691 for (Lease6Collection::iterator lease = container.begin();
1692 lease != container.end(); ++lease) {
1693 if ((*lease)->addr_ == addr) {
1700 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1711 int total = existing_leases.size();
1718 for (Lease6Collection::iterator lease = existing_leases.begin();
1719 lease != existing_leases.end(); ++lease) {
1723 if (ctx.hasGlobalReservation(resv) ||
1724 ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
1725 (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1745 "assigned-nas" :
"assigned-pds",
1746 static_cast<int64_t
>(-1));
1751 "assigned-nas" :
"assigned-pds"),
1752 static_cast<int64_t
>(-1));
1756 auto const& pool = subnet->getPool(ctx.currentIA().type_, (*lease)->addr_,
false);
1761 "pool" :
"pd-pool", pool->getID(),
1763 "assigned-nas" :
"assigned-pds")),
1764 static_cast<int64_t
>(-1));
1771 ctx.currentIA().old_leases_.push_back(*lease);
1786 existing_leases.erase(std::remove(existing_leases.begin(),
1787 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1792useMinLifetimes6(AllocEngine::ClientContext6& ctx,
const IOAddress& addr,
1793 uint8_t prefix_len) {
1794 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
1795 if (!threshold.unspecified() && (threshold < 1.0)) {
1797 getOccupancyRate(addr, prefix_len, ctx.
query_->getClasses());
1798 if (occupancy >= threshold) {
1811 if (!expired->expired()) {
1812 isc_throw(BadValue,
"Attempt to recycle lease that is still valid");
1816 isc_throw(BadValue,
"Attempt to recycle registered address");
1823 if (!ctx.fake_allocation_) {
1827 reclaimExpiredLease(expired, ctx.callout_handle_);
1831 expired->iaid_ = ctx.currentIA().iaid_;
1832 expired->duid_ = ctx.duid_;
1833 expired->hwaddr_ = ctx.hwaddr_;
1836 expired->preferred_lft_ = 0;
1837 expired->valid_lft_ = 0;
1839 useMinLifetimes6(ctx, expired->addr_, prefix_len)) {
1842 getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
1844 expired->reuseable_valid_lft_ = 0;
1846 expired->cltt_ = time(0);
1847 expired->subnet_id_ = ctx.subnet_->getID();
1848 expired->hostname_ = ctx.hostname_;
1849 expired->fqdn_fwd_ = ctx.fwd_dns_update_;
1850 expired->fqdn_rev_ = ctx.rev_dns_update_;
1851 expired->prefixlen_ = prefix_len;
1856 .arg(ctx.query_->getLabel())
1857 .arg(expired->toText());
1860 if (ctx.callout_handle_ &&
1867 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
1870 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
1875 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
1878 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
1881 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
1884 ctx.callout_handle_->setArgument(
"lease6", expired);
1889 callout_status = ctx.callout_handle_->getStatus();
1906 ctx.callout_handle_->getArgument(
"lease6", expired);
1909 if (!ctx.fake_allocation_) {
1913 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_,
false);
1915 expired->pool_id_ = pool->getID();
1923 if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
1927 "assigned-nas" :
"assigned-pds"),
1928 static_cast<int64_t
>(1));
1933 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
1934 static_cast<int64_t
>(1));
1940 "pool" :
"pd-pool", pool->getID(),
1942 "assigned-nas" :
"assigned-pds")),
1943 static_cast<int64_t
>(1));
1948 "pool" :
"pd-pool", pool->getID(),
1950 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
1951 static_cast<int64_t
>(1));
1955 "assigned-nas" :
"assigned-pds",
1956 static_cast<int64_t
>(1));
1959 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
1960 static_cast<int64_t
>(1));
1973void sanitizeLifetimes6(AllocEngine::ClientContext6& ctx,
1974 uint32_t& preferred, uint32_t& valid) {
1976 if (!preferred || preferred > valid) {
1977 preferred = ((valid * 5)/8);
1980 .arg(ctx.
query_->getLabel())
1993 if (!classes.
empty()) {
2000 for (
auto const& name : classes) {
2003 (cl && (!cl->getPreferred().unspecified()))) {
2004 candidate_preferred = cl->getPreferred();
2009 (cl && (!cl->getValid().unspecified()))) {
2010 candidate_valid = cl->getValid();
2013 if (have_both == 2) {
2020 if (!candidate_preferred) {
2021 candidate_preferred = ctx.
subnet_->getPreferred();
2025 if (!candidate_valid) {
2026 candidate_valid = ctx.
subnet_->getValid();
2030 preferred = candidate_preferred;
2031 valid = candidate_valid;
2045 sanitizeLifetimes6(ctx, preferred, valid);
2056 if (!classes.
empty()) {
2063 for (
auto const& name : classes) {
2066 (cl && (!cl->getPreferred().unspecified()))) {
2067 candidate_preferred = cl->getPreferred();
2072 (cl && (!cl->getValid().unspecified()))) {
2073 candidate_valid = cl->getValid();
2076 if (have_both == 2) {
2083 if (!candidate_preferred) {
2084 candidate_preferred = ctx.
subnet_->getPreferred();
2088 if (!candidate_valid) {
2089 candidate_valid = ctx.
subnet_->getValid();
2093 uint32_t remain_preferred(preferred);
2094 uint32_t remain_valid(valid);
2097 preferred = candidate_preferred.
getMin();
2098 valid = candidate_valid.
getMin();
2101 if (remain_preferred > preferred) {
2102 preferred = remain_preferred;
2104 if (remain_valid > valid) {
2105 valid = remain_valid;
2108 sanitizeLifetimes6(ctx, preferred, valid);
2120 uint32_t preferred = 0;
2123 useMinLifetimes6(ctx, addr, prefix_len)) {
2129 Lease6Ptr lease(
new Lease6(ctx.currentIA().type_, addr, ctx.duid_,
2130 ctx.currentIA().iaid_, preferred,
2131 valid, ctx.subnet_->getID(),
2132 ctx.hwaddr_, prefix_len));
2134 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2135 lease->fqdn_rev_ = ctx.rev_dns_update_;
2136 lease->hostname_ = ctx.hostname_;
2139 if (ctx.callout_handle_ &&
2146 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
2149 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2154 ctx.callout_handle_->setArgument(
"query6", ctx.query_);
2157 ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
2160 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
2163 ctx.callout_handle_->setArgument(
"lease6", lease);
2168 callout_status = ctx.callout_handle_->getStatus();
2180 ctx.callout_handle_->getArgument(
"lease6", lease);
2183 if (!ctx.fake_allocation_) {
2187 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2189 lease->pool_id_ = pool->getID();
2198 if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
2202 "assigned-nas" :
"assigned-pds"),
2203 static_cast<int64_t
>(1));
2208 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2209 static_cast<int64_t
>(1));
2215 "pool" :
"pd-pool", pool->getID(),
2217 "assigned-nas" :
"assigned-pds")),
2218 static_cast<int64_t
>(1));
2223 "pool" :
"pd-pool", pool->getID(),
2225 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2226 static_cast<int64_t
>(1));
2230 "assigned-nas" :
"assigned-pds",
2231 static_cast<int64_t
>(1));
2234 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2235 static_cast<int64_t
>(1));
2239 ctx.currentIA().addNewResource(addr, prefix_len);
2266 time_t now = time(0);
2268 if (lease->cltt_ > now) {
2271 uint32_t age = now - lease->cltt_;
2273 if (age >= lease->valid_lft_) {
2276 valid = lease->valid_lft_ - age;
2277 if (age >= lease->preferred_lft_) {
2280 preferred = lease->preferred_lft_ - age;
2303 for (
auto const& l : leases_subnet) {
2305 leases.push_back(l);
2308 subnet = subnet->getNextSubnet(ctx.
subnet_);
2311 if (!leases.empty()) {
2314 .arg(ctx.
query_->getLabel());
2318 removeNonmatchingReservedLeases6(ctx, leases);
2321 if (!ctx.
hosts_.empty()) {
2325 .arg(ctx.
query_->getLabel());
2328 allocateReservedLeases6(ctx, leases);
2334 removeNonreservedLeases6(ctx, leases);
2341 if (leases.empty()) {
2345 .arg(ctx.
query_->getLabel());
2347 leases = allocateUnreservedLeases6(ctx);
2351 for (
auto const& l : leases) {
2359 .arg(ctx.
query_->getLabel())
2360 .arg(l->typeToText(l->type_))
2362 extendLease6(ctx, l);
2365 if (!leases.empty()) {
2369 for (
auto const& lease : leases) {
2384 .arg(ctx.
query_->getLabel())
2394 if (!lease || !ctx.subnet_) {
2400 if (ctx.subnet_->getID() != lease->subnet_id_) {
2402 ctx.subnet_->getSharedNetwork(network);
2405 network->getSubnet(
SubnetID(lease->subnet_id_));
2409 ctx.subnet_ = subnet;
2417 (((lease->type_ !=
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
2418 !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
2433 "assigned-nas" :
"assigned-pds",
static_cast<int64_t
>(-1));
2438 "assigned-nas" :
"assigned-pds"),
2439 static_cast<int64_t
>(-1));
2441 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2446 "pool" :
"pd-pool", pool->getID(),
2448 "assigned-nas" :
"assigned-pds")),
2449 static_cast<int64_t
>(-1));
2453 ctx.currentIA().old_leases_.push_back(lease);
2460 .arg(ctx.query_->getLabel())
2461 .arg(lease->toText());
2466 bool changed =
false;
2469 uint32_t current_preferred_lft = lease->preferred_lft_;
2471 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2472 uint32_t remain_preferred_lft(0);
2473 uint32_t remain_valid_lft(0);
2474 getRemaining(lease, remain_preferred_lft, remain_valid_lft);
2475 lease->preferred_lft_ = remain_preferred_lft;
2476 lease->valid_lft_ = remain_valid_lft;
2479 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2483 if ((lease->preferred_lft_ != current_preferred_lft) ||
2484 (lease->valid_lft_ != lease->current_valid_lft_)) {
2488 lease->cltt_ = time(NULL);
2489 if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
2490 (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
2491 (lease->hostname_ != ctx.hostname_)) {
2493 lease->hostname_ = ctx.hostname_;
2494 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2495 lease->fqdn_rev_ = ctx.rev_dns_update_;
2497 if ((!ctx.hwaddr_ && lease->hwaddr_) ||
2499 (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
2501 lease->hwaddr_ = ctx.hwaddr_;
2509 .arg(ctx.query_->getLabel())
2510 .arg(lease->toText());
2514 int hook_point = ctx.query_->getType() ==
DHCPV6_RENEW ?
2515 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2523 ScopedCalloutHandleState callout_handle_state(callout_handle);
2526 ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
2529 callout_handle->setArgument(
"query6", ctx.query_);
2532 callout_handle->setArgument(
"lease6", lease);
2536 callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
2538 callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
2551 .arg(ctx.query_->getName());
2558 bool update_stats =
false;
2562 if (old_data->expired()) {
2563 reclaimExpiredLease(old_data, ctx.callout_handle_);
2567 if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
2568 update_stats =
true;
2581 setLeaseReusable(lease, current_preferred_lft, ctx);
2586 if (lease->reuseable_valid_lft_ == 0) {
2587 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2589 lease->pool_id_ = pool->getID();
2595 old_data->reuseable_valid_lft_ = lease->reuseable_valid_lft_;
2602 "assigned-nas" :
"assigned-pds"),
2603 static_cast<int64_t
>(1));
2608 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2609 static_cast<int64_t
>(1));
2611 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2616 "pool" :
"pd-pool", pool->getID(),
2618 "assigned-nas" :
"assigned-pds")),
2619 static_cast<int64_t
>(1));
2624 "pool" :
"pd-pool", pool->getID(),
2626 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2627 static_cast<int64_t
>(1));
2631 "assigned-nas" :
"assigned-pds",
2632 static_cast<int64_t
>(1));
2636 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2637 static_cast<int64_t
>(1));
2650 ctx.currentIA().changed_leases_.push_back(old_data);
2656 for (
auto const& lease_it : leases) {
2658 if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
2660 updated_leases.push_back(lease);
2664 lease->reuseable_valid_lft_ = 0;
2665 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2666 lease->fqdn_rev_ = ctx.rev_dns_update_;
2667 lease->hostname_ = ctx.hostname_;
2668 uint32_t current_preferred_lft = lease->preferred_lft_;
2669 if (lease->valid_lft_ == 0) {
2671 lease->preferred_lft_ = 0;
2673 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2676 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2679 if (!ctx.fake_allocation_) {
2680 bool update_stats =
false;
2688 if (inAllowedPool(ctx, ctx.currentIA().type_,
2689 lease->addr_,
true)) {
2690 update_stats =
true;
2695 !(lease->hasIdenticalFqdn(*lease_it)));
2697 lease->cltt_ = time(NULL);
2698 if (!fqdn_changed) {
2699 setLeaseReusable(lease, current_preferred_lft, ctx);
2702 if (lease->reuseable_valid_lft_ == 0) {
2703 ctx.currentIA().changed_leases_.push_back(lease_it);
2707 ctx.currentIA().reused_leases_.push_back(lease_it);
2714 "assigned-nas" :
"assigned-pds"),
2715 static_cast<int64_t
>(1));
2720 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2721 static_cast<int64_t
>(1));
2723 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2728 "pool" :
"pd-pool", pool->getID(),
2730 "assigned-nas" :
"assigned-pds")),
2731 static_cast<int64_t
>(1));
2736 "pool" :
"pd-pool", pool->getID(),
2738 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2739 static_cast<int64_t
>(1));
2743 "assigned-nas" :
"assigned-pds",
2744 static_cast<int64_t
>(1));
2747 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2748 static_cast<int64_t
>(1));
2752 updated_leases.push_back(lease);
2755 return (updated_leases);
2760 const uint16_t timeout,
2761 const bool remove_lease,
2762 const uint16_t max_unwarned_cycles) {
2771 max_unwarned_cycles);
2772 }
catch (
const std::exception& ex) {
2781 const uint16_t timeout,
2782 const bool remove_lease,
2783 const uint16_t max_unwarned_cycles) {
2793 bool incomplete_reclamation =
false;
2796 if (max_leases > 0) {
2805 if (leases.size() > max_leases) {
2807 incomplete_reclamation =
true;
2820 if (!leases.empty() &&
2825 size_t leases_processed = 0;
2826 for (
auto const& lease : leases) {
2834 reclaimExpiredLease(lease, remove_lease, callout_handle);
2837 reclaimExpiredLease(lease, remove_lease, callout_handle);
2841 }
catch (
const std::exception& ex) {
2843 .arg(lease->addr_.toText())
2854 if (!incomplete_reclamation) {
2855 if (leases_processed < leases.size()) {
2856 incomplete_reclamation =
true;
2873 .arg(leases_processed)
2878 if (incomplete_reclamation) {
2879 ++incomplete_v6_reclamations_;
2882 if ((max_unwarned_cycles > 0) &&
2883 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2885 .arg(max_unwarned_cycles);
2887 incomplete_v6_reclamations_ = 0;
2892 incomplete_v6_reclamations_ = 0;
2905 uint64_t deleted_leases = 0;
2911 }
catch (
const std::exception& ex) {
2918 .arg(deleted_leases);
2923 const uint16_t timeout,
2924 const bool remove_lease,
2925 const uint16_t max_unwarned_cycles) {
2934 max_unwarned_cycles);
2935 }
catch (
const std::exception& ex) {
2944 const uint16_t timeout,
2945 const bool remove_lease,
2946 const uint16_t max_unwarned_cycles) {
2956 bool incomplete_reclamation =
false;
2959 if (max_leases > 0) {
2968 if (leases.size() > max_leases) {
2970 incomplete_reclamation =
true;
2983 if (!leases.empty() &&
2988 size_t leases_processed = 0;
2989 for (
auto const& lease : leases) {
2997 reclaimExpiredLease(lease, remove_lease, callout_handle);
3000 reclaimExpiredLease(lease, remove_lease, callout_handle);
3004 }
catch (
const std::exception& ex) {
3006 .arg(lease->addr_.toText())
3017 if (!incomplete_reclamation) {
3018 if (leases_processed < leases.size()) {
3019 incomplete_reclamation =
true;
3036 .arg(leases_processed)
3041 if (incomplete_reclamation) {
3042 ++incomplete_v4_reclamations_;
3045 if ((max_unwarned_cycles > 0) &&
3046 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
3048 .arg(max_unwarned_cycles);
3050 incomplete_v4_reclamations_ = 0;
3055 incomplete_v4_reclamations_ = 0;
3062template<
typename LeasePtrType>
3064AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
3066 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
3070template<
typename LeasePtrType>
3072AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
3077 if (!lease->stateExpiredReclaimed()) {
3078 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
3083AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
3084 const DbReclaimMode& reclaim_mode,
3090 .arg(lease->addr_.toText())
3091 .arg(
static_cast<int>(lease->prefixlen_));
3097 bool skipped =
false;
3100 if (callout_handle) {
3106 ScopedCalloutHandleState callout_handle_state(callout_handle);
3108 callout_handle->deleteAllArguments();
3109 callout_handle->setArgument(
"lease6", lease);
3110 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3130 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3140 remove_lease = reclaimDeclined(lease);
3142 if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
3143 isc_throw(Unexpected,
"attempt to reuse a registered lease");
3146 remove_lease =
true;
3149 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3153 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
3155 &lease_mgr, ph::_1));
3167 "reclaimed-leases"),
3168 static_cast<int64_t
>(1));
3174 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3180 pool->getID(),
"reclaimed-leases")),
3181 static_cast<int64_t
>(1));
3197 static_cast<int64_t
>(-1));
3201 "assigned-nas" :
"assigned-pds",
3202 static_cast<int64_t
>(-1));
3207 "assigned-nas" :
"assigned-pds"),
3208 static_cast<int64_t
>(-1));
3211 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3216 "pool" :
"pd-pool", pool->getID(),
3218 "assigned-nas" :
"assigned-pds")),
3219 static_cast<int64_t
>(-1));
3226AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
3227 const DbReclaimMode& reclaim_mode,
3233 .arg(lease->addr_.toText());
3239 bool skipped =
false;
3241 if (callout_handle) {
3247 ScopedCalloutHandleState callout_handle_state(callout_handle);
3249 callout_handle->setArgument(
"lease4", lease);
3250 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3268 lease->hostname_.clear();
3269 lease->fqdn_fwd_ =
false;
3270 lease->fqdn_rev_ =
false;
3274 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3284 remove_lease = reclaimDeclined(lease);
3287 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3291 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
3293 &lease_mgr, ph::_1));
3305 "reclaimed-leases"),
3306 static_cast<int64_t
>(1));
3311 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3316 "reclaimed-leases")),
3317 static_cast<int64_t
>(1));
3331 "assigned-addresses"),
3332 static_cast<int64_t
>(-1));
3335 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3340 "assigned-addresses")),
3341 static_cast<int64_t
>(-1));
3352 uint64_t deleted_leases = 0;
3358 }
catch (
const std::exception& ex) {
3365 .arg(deleted_leases);
3369AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3384 callout_handle->setArgument(
"lease4", lease);
3394 .arg(lease->addr_.toText());
3400 .arg(lease->addr_.toText())
3401 .arg(lease->valid_lft_);
3407 "declined-addresses"),
3408 static_cast<int64_t
>(-1));
3411 "reclaimed-declined-addresses"),
3412 static_cast<int64_t
>(1));
3416 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3420 "declined-addresses")),
3421 static_cast<int64_t
>(-1));
3425 "reclaimed-declined-addresses")),
3426 static_cast<int64_t
>(1));
3431 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3433 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3441AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3453 ScopedCalloutHandleState callout_handle_state(callout_handle);
3456 callout_handle->setArgument(
"lease6", lease);
3466 .arg(lease->addr_.toText());
3472 .arg(lease->addr_.toText())
3473 .arg(lease->valid_lft_);
3479 "declined-addresses"),
3480 static_cast<int64_t
>(-1));
3483 "reclaimed-declined-addresses"),
3484 static_cast<int64_t
>(1));
3488 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3492 "declined-addresses")),
3493 static_cast<int64_t
>(-1));
3497 "reclaimed-declined-addresses")),
3498 static_cast<int64_t
>(1));
3503 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3505 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3514 lease->relay_id_.clear();
3515 lease->remote_id_.clear();
3516 if (lease->getContext()) {
3523 if (lease->getContext()) {
3529template<
typename LeasePtrType>
3530void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3531 const bool remove_lease,
3532 const std::function<
void (
const LeasePtrType&)>&
3533 lease_update_fun)
const {
3541 }
else if (lease_update_fun) {
3544 lease->reuseable_valid_lft_ = 0;
3545 lease->hostname_.clear();
3546 lease->fqdn_fwd_ =
false;
3547 lease->fqdn_rev_ =
false;
3550 lease_update_fun(lease);
3559 .arg(lease->addr_.toText());
3565 return(
"<empty subnet>");
3569 subnet->getSharedNetwork(network);
3570 std::ostringstream ss;
3572 ss <<
"shared-network: " << network->getName();
3574 ss <<
"subnet id: " << subnet->getID();
3613 (!ctx.
subnet_->getReservationsOutOfPool() ||
3624 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
3629 hosts.push_back(host);
3643 for (
auto const& host : hosts) {
3647 if (id_pair.first == host->getIdentifierType() &&
3648 id_pair.second == host->getIdentifier()) {
3656 return (!hosts.empty());
3680 if (ctx.
hosts_.empty()) {
3686 std::list<ConstSubnet4Ptr> eligible_subnets;
3691 eligible_subnets.push_back(subnet);
3692 if (subnet->getReservationsInSubnet()) {
3693 auto host = ctx.
hosts_.find(subnet->getID());
3698 if (host != ctx.
hosts_.end() && host->second) {
3699 auto reservation = host->second->getIPv4Reservation();
3700 if (!reservation.isV4Zero() &&
3701 (!subnet->getReservationsOutOfPool() ||
3709 if (reservation.isV4Zero()) {
3718 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3722 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3723 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3724 global_host->second->getIPv4Reservation() :
3733 for (
auto eligible_subnet : eligible_subnets) {
3737 if (eligible_subnet->getReservationsGlobal() &&
3739 (eligible_subnet->inRange(global_host_address))) {
3740 ctx.
subnet_ = eligible_subnet;
3748 .arg(ctx.
query_->getLabel())
3749 .arg(global_host_address.toText())
3776 auto const& classes = ctx.
query_->getClasses();
3780 bool try_clientid_lookup = (ctx.
clientid_ &&
3784 if (try_clientid_lookup) {
3793 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3798 if (subnet->getMatchClientId()) {
3799 for (
auto const& l : leases_client_id) {
3800 if (l->subnet_id_ == subnet->getID()) {
3813 if (!client_lease && ctx.
hwaddr_) {
3819 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3821 if (subnet->getMatchClientId()) {
3827 for (
auto const& client_lease_it : leases_hw_address) {
3828 Lease4Ptr existing_lease = client_lease_it;
3829 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3830 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3832 client_lease = existing_lease;
3860 auto const& classes = ctx.
query_->getClasses();
3862 while (current_subnet) {
3871 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3898 const bool fwd_dns_update,
3899 const bool rev_dns_update,
3900 const std::string& hostname,
3901 const bool fake_allocation,
3902 const uint32_t offer_lft)
3922 if (host !=
hosts_.cend()) {
3923 return (host->second);
3933 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3934 if (host !=
hosts_.cend()) {
3935 return (host->second);
3945 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3946 return (ddns_params_);
3952 return (ddns_params_);
3974 auto const& classes = ctx.
query_->getClasses();
3975 if (subnet && !subnet->clientSupported(classes)) {
3976 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
4000 .arg(ctx.
query_->getLabel())
4018 !subnet->getReservationsInSubnet()) {
4024 subnet->getReservationsGlobal()) {
4027 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
4030 if (!subnet->getReservationsInSubnet()) {
4036 std::map<SubnetID, ConstHostPtr> host_map;
4038 subnet->getSharedNetwork(network);
4047 const bool use_single_query = network &&
4051 if (use_single_query) {
4055 id_pair.second.size());
4059 for (
auto const& host : hosts) {
4060 if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
4061 host_map[host->getIPv4SubnetID()] = host;
4067 auto const& classes = ctx.
query_->getClasses();
4073 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
4076 if (use_single_query) {
4077 if (host_map.count(subnet->getID()) > 0) {
4078 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
4086 id_pair.second.size());
4089 ctx.
hosts_[subnet->getID()] = host;
4099 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
4105 for (
auto const& host : ctx.
hosts_) {
4106 host.second->encapsulateOptions();
4116 &id_pair.second[0], id_pair.second.size());
4133 findClientLease(ctx, client_lease);
4146 if (hasAddressReservation(ctx)) {
4150 .arg(ctx.
query_->getLabel())
4151 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
4157 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
4164 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
4168 .arg(ctx.
query_->getLabel())
4169 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4175 "v4-reservation-conflicts"),
4176 static_cast<int64_t
>(1));
4178 static_cast<int64_t
>(1));
4183 new_lease = renewLease4(client_lease, ctx);
4196 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
4197 !addressReserved(client_lease->addr_, ctx)) {
4201 .arg(ctx.
query_->getLabel());
4207 (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
4211 new_lease = renewLease4(client_lease, ctx);
4228 .arg(ctx.
query_->getLabel());
4241 .arg(ctx.
query_->getLabel());
4243 new_lease = allocateUnreservedLease4(ctx);
4264 "assigned-addresses"),
4265 static_cast<int64_t
>(-1));
4268 ->getBySubnetId(lease->subnet_id_);
4270 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4274 "assigned-addresses")),
4275 static_cast<int64_t
>(-1));
4287 findClientLease(ctx, client_lease);
4303 .arg(ctx.
query_->getLabel())
4309 }
else if (hasAddressReservation(ctx)) {
4318 .arg(ctx.
query_->getLabel())
4330 if (existing && !existing->expired() &&
4331 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4336 .arg(ctx.
query_->getLabel())
4346 if (hasAddressReservation(ctx) &&
4354 if (!existing || existing->expired()) {
4358 .arg(ctx.
query_->getLabel())
4359 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4369 if ((!hasAddressReservation(ctx) ||
4375 .arg(ctx.
query_->getLabel())
4387 if (((client_lease && existing) && (client_lease->addr_ != existing->addr_) &&
4389 (existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
4392 auto conflicted_lease = client_lease;
4393 client_lease = existing;
4410 ((hasAddressReservation(ctx) &&
4412 inAllowedPool(ctx, client_lease->addr_))) {
4416 .arg(ctx.
query_->getLabel())
4418 return (renewLease4(client_lease, ctx));
4432 .arg(ctx.
query_->getLabel())
4447 .arg(ctx.
query_->getLabel());
4452 new_lease = allocateUnreservedLease4(ctx);
4458 if (new_lease && client_lease) {
4463 .arg(ctx.
query_->getLabel())
4464 .arg(client_lease->addr_.toText());
4485 if (!classes.
empty()) {
4491 for (
auto const& name : classes) {
4493 if (cl && (!cl->getOfferLft().unspecified())) {
4494 offer_lft = cl->getOfferLft();
4502 offer_lft = ctx.
subnet_->getOfferLft();
4511 if (ctx.
query_->inClass(
"BOOTP")) {
4516 uint32_t requested_lft = 0;
4519 OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
4521 requested_lft = opt_lft->getValue();
4529 if (!classes.
empty()) {
4535 for (
auto const& name : classes) {
4537 if (cl && (!cl->getValid().unspecified())) {
4538 candidate_lft = cl->getValid();
4545 if (!candidate_lft) {
4546 candidate_lft = ctx.
subnet_->getValid();
4551 if (requested_lft > 0) {
4552 return (candidate_lft.
get(requested_lft));
4556 return (candidate_lft.
get());
4562 if (ctx.
query_->inClass(
"BOOTP")) {
4571 if (!classes.
empty()) {
4577 for (
auto const& name : classes) {
4579 if (cl && (!cl->getValid().unspecified())) {
4580 candidate_lft = cl->getValid();
4587 if (!candidate_lft) {
4588 candidate_lft = ctx.
subnet_->getValid();
4592 uint32_t remain(valid);
4595 valid = candidate_lft.
getMin();
4598 if (remain > valid) {
4606 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
4607 if (!threshold.unspecified() && (threshold < 1.0)) {
4609 getOccupancyRate(addr, ctx.
query_->getClasses());
4610 if (occupancy >= threshold) {
4619AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
4622 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
4625 isc_throw(BadValue,
"Can't create a lease without a subnet");
4629 uint32_t valid_lft = ctx.offer_lft_;
4631 if (useMinValidLft(ctx, addr)) {
4638 time_t now = time(0);
4641 if (ctx.subnet_->getMatchClientId()) {
4642 client_id = ctx.clientid_;
4645 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
4646 valid_lft, now, ctx.subnet_->getID()));
4649 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
4650 lease->fqdn_rev_ = ctx.rev_dns_update_;
4651 lease->hostname_ = ctx.hostname_;
4657 if (ctx.callout_handle_ &&
4664 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
4667 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
4671 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
4678 boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
4679 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
4682 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
4685 ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
4688 ctx.callout_handle_->setArgument(
"lease4", lease);
4693 callout_status = ctx.callout_handle_->getStatus();
4705 ctx.callout_handle_->getArgument(
"lease4", lease);
4708 if (ctx.fake_allocation_ && ctx.offer_lft_) {
4712 lease->fqdn_fwd_ =
false;
4713 lease->fqdn_rev_ =
false;
4716 if (!ctx.fake_allocation_ || ctx.offer_lft_) {
4717 auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4719 lease->pool_id_ = pool->getID();
4728 "assigned-addresses"),
4729 static_cast<int64_t
>(1));
4733 "cumulative-assigned-addresses"),
4734 static_cast<int64_t
>(1));
4740 "assigned-addresses")),
4741 static_cast<int64_t
>(1));
4746 "cumulative-assigned-addresses")),
4747 static_cast<int64_t
>(1));
4782 time_t now = time(0);
4784 if (lease->cltt_ > now) {
4787 uint32_t age = now - lease->cltt_;
4789 if (age >= lease->valid_lft_) {
4792 valid = lease->valid_lft_ - age;
4796AllocEngine::renewLease4(
const Lease4Ptr& lease,
4806 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4811 lease->reuseable_valid_lft_ = 0;
4812 if (!updateLease4Information(lease, ctx)) {
4813 setLeaseReusable(lease, ctx);
4838 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4845 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4854 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4880 lease->pool_id_ = pool->getID();
4890 "assigned-addresses"),
4891 static_cast<int64_t
>(1));
4895 "cumulative-assigned-addresses"),
4896 static_cast<int64_t
>(1));
4902 "assigned-addresses")),
4903 static_cast<int64_t
>(1));
4908 "cumulative-assigned-addresses")),
4909 static_cast<int64_t
>(1));
4920 *lease = *old_values;
4927AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4928 AllocEngine::ClientContext4& ctx,
4931 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
4935 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
4946 expired->reuseable_valid_lft_ = 0;
4947 static_cast<void>(updateLease4Information(expired, ctx));
4951 .arg(ctx.
query_->getLabel())
4952 .arg(expired->toText());
4959 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4976 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
5010 expired->pool_id_ = pool->getID();
5018 "assigned-addresses"),
5019 static_cast<int64_t
>(1));
5023 "cumulative-assigned-addresses"),
5024 static_cast<int64_t
>(1));
5030 "assigned-addresses")),
5031 static_cast<int64_t
>(1));
5036 "cumulative-assigned-addresses")),
5037 static_cast<int64_t
>(1));
5054AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate,
ClientContext4& ctx,
5056 ctx.conflicting_lease_.reset();
5060 if (exist_lease->expired()) {
5061 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5065 ctx.old_lease_->hostname_.clear();
5066 ctx.old_lease_->fqdn_fwd_ =
false;
5067 ctx.old_lease_->fqdn_rev_ =
false;
5068 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
5074 ctx.conflicting_lease_ = exist_lease;
5078 return (createLease4(ctx, candidate, callout_status));
5098 ctx.subnet_->getSharedNetwork(network);
5105 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
5119 uint64_t subnets_with_unavail_leases = 0;
5122 uint64_t subnets_with_unavail_pools = 0;
5124 auto const& classes = ctx.query_->getClasses();
5128 if (subnet->getMatchClientId()) {
5129 client_id = ctx.clientid_;
5141 (attempts_ == 0 || possible_attempts < attempts_) ?
5145 if (max_attempts > 0) {
5148 ++subnets_with_unavail_leases;
5152 ++subnets_with_unavail_pools;
5155 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
5160 for (
uint128_t i = 0; i < max_attempts; ++i) {
5165 IOAddress candidate = allocator->pickAddress(classes,
5167 ctx.requested_address_);
5174 if (exclude_first_last_24) {
5176 auto const& bytes = candidate.
toBytes();
5177 if ((bytes.size() != 4) ||
5178 (bytes[3] == 0) || (bytes[3] == 255U)) {
5185 if (check_reservation_first && addressReserved(candidate, ctx)) {
5192 ResourceHandler4 resource_handler;
5194 !resource_handler.
tryLock4(candidate)) {
5203 if (check_reservation_first || !addressReserved(candidate, ctx)) {
5205 new_lease = createLease4(ctx, candidate, callout_status);
5209 if (exist_lease->expired() &&
5210 (check_reservation_first || !addressReserved(candidate, ctx))) {
5211 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5212 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
5230 subnet = subnet->getNextSubnet(original_subnet, classes);
5233 ctx.subnet_ = subnet;
5242 .arg(ctx.query_->getLabel())
5243 .arg(network->getName())
5244 .arg(subnets_with_unavail_leases)
5245 .arg(subnets_with_unavail_pools);
5247 static_cast<int64_t
>(1));
5250 "v4-allocation-fail-shared-network"),
5251 static_cast<int64_t
>(1));
5255 std::string shared_network = ctx.subnet_->getSharedNetworkName();
5256 if (shared_network.empty()) {
5257 shared_network =
"(none)";
5260 .arg(ctx.query_->getLabel())
5261 .arg(ctx.subnet_->toText())
5262 .arg(ctx.subnet_->getID())
5263 .arg(shared_network);
5265 static_cast<int64_t
>(1));
5268 "v4-allocation-fail-subnet"),
5269 static_cast<int64_t
>(1));
5271 if (total_attempts == 0) {
5277 .arg(ctx.query_->getLabel());
5279 static_cast<int64_t
>(1));
5282 "v4-allocation-fail-no-pools"),
5283 static_cast<int64_t
>(1));
5290 .arg(ctx.query_->getLabel())
5291 .arg(total_attempts);
5293 static_cast<int64_t
>(1));
5296 "v4-allocation-fail"),
5297 static_cast<int64_t
>(1));
5300 if (!classes.empty()) {
5302 .arg(ctx.query_->getLabel())
5303 .arg(classes.toText());
5305 static_cast<int64_t
>(1));
5308 "v4-allocation-fail-classes"),
5309 static_cast<int64_t
>(1));
5316AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
5317 AllocEngine::ClientContext4& ctx)
const {
5318 bool changed =
false;
5319 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
5321 lease->subnet_id_ = ctx.
subnet_->getID();
5323 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
5325 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
5330 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
5334 }
else if (lease->client_id_) {
5338 uint32_t remain_lft(0);
5340 lease->cltt_ = time(0);
5344 if (!lease->valid_lft_) {
5345 if (useMinValidLft(ctx, lease->addr_)) {
5346 lease->valid_lft_ = remain_lft;
5354 if (lease->valid_lft_ != lease->current_valid_lft_) {
5378 bool changed =
false;
5381 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5396 sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
5405 extended_info->set(
"sub-options", relay_agent);
5409 std::vector<uint8_t> bytes = remote_id->toBinary();
5410 lease->remote_id_ = bytes;
5411 if (bytes.size() > 0) {
5412 extended_info->set(
"remote-id",
5419 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5420 lease->relay_id_ = bytes;
5421 if (bytes.size() > 0) {
5422 extended_info->set(
"relay-id",
5428 return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
5438 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5443 if (ctx.
query_->relay_info_.empty()) {
5458 for (
auto const& relay : ctx.
query_->relay_info_) {
5467 if (!relay.options_.empty()) {
5472 const uint8_t* cp = buf.
getData();
5473 std::vector<uint8_t> bytes;
5474 std::stringstream ss;
5482 if (remote_id_it != relay.options_.end()) {
5483 OptionPtr remote_id = remote_id_it->second;
5485 std::vector<uint8_t> bytes = remote_id->toBinary();
5486 if (bytes.size() > 0) {
5487 relay_elem->set(
"remote-id",
5494 if (relay_id_it != relay.options_.end()) {
5495 OptionPtr relay_id = relay_id_it->second;
5497 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5498 if (bytes.size() > 0) {
5499 relay_elem->set(
"relay-id",
5506 extended_info->add(relay_elem);
5510 if (lease->updateUserContextISC(
"relay-info", extended_info)) {
5516AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
5517 const ClientContext4& ctx)
const {
5519 lease->reuseable_valid_lft_ = 0;
5535 if (lease->cltt_ < lease->current_cltt_) {
5539 uint32_t age = lease->cltt_ - lease->current_cltt_;
5541 if (age >= lease->current_valid_lft_) {
5546 uint32_t max_age = 0;
5547 if (!subnet->getCacheMaxAge().unspecified()) {
5548 max_age = subnet->getCacheMaxAge().get();
5549 if ((max_age == 0) || (age > max_age)) {
5555 if (!subnet->getCacheThreshold().unspecified()) {
5556 double threshold = subnet->getCacheThreshold().get();
5557 if ((threshold <= 0.) || (threshold > 1.)) {
5560 max_age = lease->valid_lft_ * threshold;
5561 if (age > max_age) {
5572 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
5576AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
5577 uint32_t current_preferred_lft,
5580 lease->reuseable_valid_lft_ = 0;
5581 lease->reuseable_preferred_lft_ = 0;
5591 if (lease->cltt_ < lease->current_cltt_) {
5595 uint32_t age = lease->cltt_ - lease->current_cltt_;
5597 if (age >= lease->current_valid_lft_) {
5602 uint32_t max_age = 0;
5603 if (!subnet->getCacheMaxAge().unspecified()) {
5604 max_age = subnet->getCacheMaxAge().get();
5605 if ((max_age == 0) || (age > max_age)) {
5611 if (!subnet->getCacheThreshold().unspecified()) {
5612 double threshold = subnet->getCacheThreshold().get();
5613 if ((threshold <= 0.) || (threshold > 1.)) {
5616 max_age = lease->valid_lft_ * threshold;
5617 if (age > max_age) {
5629 (current_preferred_lft == 0)) {
5631 lease->reuseable_preferred_lft_ = current_preferred_lft;
5632 }
else if (current_preferred_lft > age) {
5633 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
5641 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