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 if (lease->expired()) {
2666 lease->valid_lft_ = 0;
2667 lease->preferred_lft_ = 0;
2670 lease->reuseable_valid_lft_ = 0;
2671 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
2672 lease->fqdn_rev_ = ctx.rev_dns_update_;
2673 lease->hostname_ = ctx.hostname_;
2674 uint32_t current_preferred_lft = lease->preferred_lft_;
2675 if (lease->valid_lft_ == 0) {
2677 lease->preferred_lft_ = 0;
2679 useMinLifetimes6(ctx, lease->addr_, lease->prefixlen_)) {
2682 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2685 if (!ctx.fake_allocation_) {
2686 bool update_stats =
false;
2694 if (inAllowedPool(ctx, ctx.currentIA().type_,
2695 lease->addr_,
true)) {
2696 update_stats =
true;
2701 !(lease->hasIdenticalFqdn(*lease_it)));
2703 lease->cltt_ = time(NULL);
2704 if (!fqdn_changed) {
2705 setLeaseReusable(lease, current_preferred_lft, ctx);
2708 if (lease->reuseable_valid_lft_ == 0) {
2709 ctx.currentIA().changed_leases_.push_back(lease_it);
2713 ctx.currentIA().reused_leases_.push_back(lease_it);
2720 "assigned-nas" :
"assigned-pds"),
2721 static_cast<int64_t
>(1));
2726 "cumulative-assigned-nas" :
"cumulative-assigned-pds"),
2727 static_cast<int64_t
>(1));
2729 auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_,
false);
2734 "pool" :
"pd-pool", pool->getID(),
2736 "assigned-nas" :
"assigned-pds")),
2737 static_cast<int64_t
>(1));
2742 "pool" :
"pd-pool", pool->getID(),
2744 "cumulative-assigned-nas" :
"cumulative-assigned-pds")),
2745 static_cast<int64_t
>(1));
2749 "assigned-nas" :
"assigned-pds",
2750 static_cast<int64_t
>(1));
2753 "cumulative-assigned-nas" :
"cumulative-assigned-pds",
2754 static_cast<int64_t
>(1));
2758 updated_leases.push_back(lease);
2761 return (updated_leases);
2766 const uint16_t timeout,
2767 const bool remove_lease,
2768 const uint16_t max_unwarned_cycles) {
2777 max_unwarned_cycles);
2778 }
catch (
const std::exception& ex) {
2787 const uint16_t timeout,
2788 const bool remove_lease,
2789 const uint16_t max_unwarned_cycles) {
2799 bool incomplete_reclamation =
false;
2802 if (max_leases > 0) {
2811 if (leases.size() > max_leases) {
2813 incomplete_reclamation =
true;
2826 if (!leases.empty() &&
2831 size_t leases_processed = 0;
2832 for (
auto const& lease : leases) {
2840 reclaimExpiredLease(lease, remove_lease, callout_handle);
2843 reclaimExpiredLease(lease, remove_lease, callout_handle);
2847 }
catch (
const std::exception& ex) {
2849 .arg(lease->addr_.toText())
2860 if (!incomplete_reclamation) {
2861 if (leases_processed < leases.size()) {
2862 incomplete_reclamation =
true;
2879 .arg(leases_processed)
2884 if (incomplete_reclamation) {
2885 ++incomplete_v6_reclamations_;
2888 if ((max_unwarned_cycles > 0) &&
2889 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2891 .arg(max_unwarned_cycles);
2893 incomplete_v6_reclamations_ = 0;
2898 incomplete_v6_reclamations_ = 0;
2911 uint64_t deleted_leases = 0;
2917 }
catch (
const std::exception& ex) {
2924 .arg(deleted_leases);
2929 const uint16_t timeout,
2930 const bool remove_lease,
2931 const uint16_t max_unwarned_cycles) {
2940 max_unwarned_cycles);
2941 }
catch (
const std::exception& ex) {
2950 const uint16_t timeout,
2951 const bool remove_lease,
2952 const uint16_t max_unwarned_cycles) {
2962 bool incomplete_reclamation =
false;
2965 if (max_leases > 0) {
2974 if (leases.size() > max_leases) {
2976 incomplete_reclamation =
true;
2989 if (!leases.empty() &&
2994 size_t leases_processed = 0;
2995 for (
auto const& lease : leases) {
3003 reclaimExpiredLease(lease, remove_lease, callout_handle);
3006 reclaimExpiredLease(lease, remove_lease, callout_handle);
3010 }
catch (
const std::exception& ex) {
3012 .arg(lease->addr_.toText())
3023 if (!incomplete_reclamation) {
3024 if (leases_processed < leases.size()) {
3025 incomplete_reclamation =
true;
3042 .arg(leases_processed)
3047 if (incomplete_reclamation) {
3048 ++incomplete_v4_reclamations_;
3051 if ((max_unwarned_cycles > 0) &&
3052 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
3054 .arg(max_unwarned_cycles);
3056 incomplete_v4_reclamations_ = 0;
3061 incomplete_v4_reclamations_ = 0;
3068template<
typename LeasePtrType>
3070AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
3072 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
3076template<
typename LeasePtrType>
3078AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
3083 if (!lease->stateExpiredReclaimed()) {
3084 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
3089AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
3090 const DbReclaimMode& reclaim_mode,
3096 .arg(lease->addr_.toText())
3097 .arg(
static_cast<int>(lease->prefixlen_));
3103 bool skipped =
false;
3106 if (callout_handle) {
3112 ScopedCalloutHandleState callout_handle_state(callout_handle);
3114 callout_handle->deleteAllArguments();
3115 callout_handle->setArgument(
"lease6", lease);
3116 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3136 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3146 remove_lease = reclaimDeclined(lease);
3148 if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
3149 isc_throw(Unexpected,
"attempt to reuse a registered lease");
3152 remove_lease =
true;
3155 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3159 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
3161 &lease_mgr, ph::_1));
3173 "reclaimed-leases"),
3174 static_cast<int64_t
>(1));
3180 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3186 pool->getID(),
"reclaimed-leases")),
3187 static_cast<int64_t
>(1));
3203 static_cast<int64_t
>(-1));
3207 "assigned-nas" :
"assigned-pds",
3208 static_cast<int64_t
>(-1));
3213 "assigned-nas" :
"assigned-pds"),
3214 static_cast<int64_t
>(-1));
3217 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3222 "pool" :
"pd-pool", pool->getID(),
3224 "assigned-nas" :
"assigned-pds")),
3225 static_cast<int64_t
>(-1));
3232AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
3233 const DbReclaimMode& reclaim_mode,
3239 .arg(lease->addr_.toText());
3245 bool skipped =
false;
3247 if (callout_handle) {
3253 ScopedCalloutHandleState callout_handle_state(callout_handle);
3255 callout_handle->setArgument(
"lease4", lease);
3256 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
3274 lease->hostname_.clear();
3275 lease->fqdn_fwd_ =
false;
3276 lease->fqdn_rev_ =
false;
3280 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
3290 remove_lease = reclaimDeclined(lease);
3293 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
3297 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
3299 &lease_mgr, ph::_1));
3311 "reclaimed-leases"),
3312 static_cast<int64_t
>(1));
3317 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3322 "reclaimed-leases")),
3323 static_cast<int64_t
>(1));
3337 "assigned-addresses"),
3338 static_cast<int64_t
>(-1));
3341 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3346 "assigned-addresses")),
3347 static_cast<int64_t
>(-1));
3358 uint64_t deleted_leases = 0;
3364 }
catch (
const std::exception& ex) {
3371 .arg(deleted_leases);
3375AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3390 callout_handle->setArgument(
"lease4", lease);
3400 .arg(lease->addr_.toText());
3406 .arg(lease->addr_.toText())
3407 .arg(lease->valid_lft_);
3413 "declined-addresses"),
3414 static_cast<int64_t
>(-1));
3417 "reclaimed-declined-addresses"),
3418 static_cast<int64_t
>(1));
3422 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
3426 "declined-addresses")),
3427 static_cast<int64_t
>(-1));
3431 "reclaimed-declined-addresses")),
3432 static_cast<int64_t
>(1));
3437 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3439 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3447AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3459 ScopedCalloutHandleState callout_handle_state(callout_handle);
3462 callout_handle->setArgument(
"lease6", lease);
3472 .arg(lease->addr_.toText());
3478 .arg(lease->addr_.toText())
3479 .arg(lease->valid_lft_);
3485 "declined-addresses"),
3486 static_cast<int64_t
>(-1));
3489 "reclaimed-declined-addresses"),
3490 static_cast<int64_t
>(1));
3494 auto const& pool = subnet->getPool(lease->type_, lease->addr_,
false);
3498 "declined-addresses")),
3499 static_cast<int64_t
>(-1));
3503 "reclaimed-declined-addresses")),
3504 static_cast<int64_t
>(1));
3509 stats_mgr.
addValue(
"declined-addresses",
static_cast<int64_t
>(-1));
3511 stats_mgr.
addValue(
"reclaimed-declined-addresses",
static_cast<int64_t
>(1));
3520 lease->relay_id_.clear();
3521 lease->remote_id_.clear();
3522 if (lease->getContext()) {
3529 if (lease->getContext()) {
3535template<
typename LeasePtrType>
3536void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3537 const bool remove_lease,
3538 const std::function<
void (
const LeasePtrType&)>&
3539 lease_update_fun)
const {
3547 }
else if (lease_update_fun) {
3550 lease->reuseable_valid_lft_ = 0;
3551 lease->hostname_.clear();
3552 lease->fqdn_fwd_ =
false;
3553 lease->fqdn_rev_ =
false;
3556 lease_update_fun(lease);
3565 .arg(lease->addr_.toText());
3571 return(
"<empty subnet>");
3575 subnet->getSharedNetwork(network);
3576 std::ostringstream ss;
3578 ss <<
"shared-network: " << network->getName();
3580 ss <<
"subnet id: " << subnet->getID();
3619 (!ctx.
subnet_->getReservationsOutOfPool() ||
3630 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
3635 hosts.push_back(host);
3649 for (
auto const& host : hosts) {
3653 if (id_pair.first == host->getIdentifierType() &&
3654 id_pair.second == host->getIdentifier()) {
3662 return (!hosts.empty());
3686 if (ctx.
hosts_.empty()) {
3692 std::list<ConstSubnet4Ptr> eligible_subnets;
3697 eligible_subnets.push_back(subnet);
3698 if (subnet->getReservationsInSubnet()) {
3699 auto host = ctx.
hosts_.find(subnet->getID());
3704 if (host != ctx.
hosts_.end() && host->second) {
3705 auto reservation = host->second->getIPv4Reservation();
3706 if (!reservation.isV4Zero() &&
3707 (!subnet->getReservationsOutOfPool() ||
3715 if (reservation.isV4Zero()) {
3724 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3728 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3729 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3730 global_host->second->getIPv4Reservation() :
3739 for (
auto eligible_subnet : eligible_subnets) {
3743 if (eligible_subnet->getReservationsGlobal() &&
3745 (eligible_subnet->inRange(global_host_address))) {
3746 ctx.
subnet_ = eligible_subnet;
3754 .arg(ctx.
query_->getLabel())
3755 .arg(global_host_address.toText())
3780 bool hwaddr_empty = (!ctx.
hwaddr_ || ctx.
hwaddr_->hwaddr_.empty());
3786 auto const& classes = ctx.
query_->getClasses();
3790 bool try_clientid_lookup = (ctx.
clientid_ &&
3794 if (try_clientid_lookup || hwaddr_empty) {
3803 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3808 if (subnet->getMatchClientId() || hwaddr_empty) {
3809 for (
auto const& l : leases_client_id) {
3810 if (l->subnet_id_ == subnet->getID()) {
3823 if (!client_lease && !hwaddr_empty) {
3829 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3831 if (subnet->getMatchClientId()) {
3837 for (
auto const& client_lease_it : leases_hw_address) {
3838 Lease4Ptr existing_lease = client_lease_it;
3839 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3840 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3842 client_lease = existing_lease;
3870 auto const& classes = ctx.
query_->getClasses();
3872 while (current_subnet) {
3881 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3908 const bool fwd_dns_update,
3909 const bool rev_dns_update,
3910 const std::string& hostname,
3911 const bool fake_allocation,
3912 const uint32_t offer_lft)
3923 if (hwaddr && !hwaddr->hwaddr_.empty()) {
3924 addHostIdentifier(Host::IDENT_HWADDR, hwaddr->hwaddr_);
3932 if (host !=
hosts_.cend()) {
3933 return (host->second);
3943 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3944 if (host !=
hosts_.cend()) {
3945 return (host->second);
3955 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3956 return (ddns_params_);
3962 return (ddns_params_);
3984 auto const& classes = ctx.
query_->getClasses();
3985 if (subnet && !subnet->clientSupported(classes)) {
3986 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
4010 .arg(ctx.
query_->getLabel())
4028 !subnet->getReservationsInSubnet()) {
4034 subnet->getReservationsGlobal()) {
4037 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
4040 if (!subnet->getReservationsInSubnet()) {
4046 std::map<SubnetID, ConstHostPtr> host_map;
4048 subnet->getSharedNetwork(network);
4057 const bool use_single_query = network &&
4061 if (use_single_query) {
4065 id_pair.second.size());
4069 for (
auto const& host : hosts) {
4070 if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
4071 host_map[host->getIPv4SubnetID()] = host;
4077 auto const& classes = ctx.
query_->getClasses();
4083 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
4086 if (use_single_query) {
4087 if (host_map.count(subnet->getID()) > 0) {
4088 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
4096 id_pair.second.size());
4099 ctx.
hosts_[subnet->getID()] = host;
4109 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
4115 for (
auto const& host : ctx.
hosts_) {
4116 host.second->encapsulateOptions();
4126 &id_pair.second[0], id_pair.second.size());
4143 findClientLease(ctx, client_lease);
4156 if (hasAddressReservation(ctx)) {
4160 .arg(ctx.
query_->getLabel())
4161 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
4167 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
4174 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
4178 .arg(ctx.
query_->getLabel())
4179 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4185 "v4-reservation-conflicts"),
4186 static_cast<int64_t
>(1));
4188 static_cast<int64_t
>(1));
4193 new_lease = renewLease4(client_lease, ctx);
4206 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
4207 !addressReserved(client_lease->addr_, ctx)) {
4211 .arg(ctx.
query_->getLabel());
4217 (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
4221 new_lease = renewLease4(client_lease, ctx);
4238 .arg(ctx.
query_->getLabel());
4251 .arg(ctx.
query_->getLabel());
4253 new_lease = allocateUnreservedLease4(ctx);
4274 "assigned-addresses"),
4275 static_cast<int64_t
>(-1));
4278 ->getBySubnetId(lease->subnet_id_);
4280 auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4284 "assigned-addresses")),
4285 static_cast<int64_t
>(-1));
4297 findClientLease(ctx, client_lease);
4313 .arg(ctx.
query_->getLabel())
4319 }
else if (hasAddressReservation(ctx)) {
4328 .arg(ctx.
query_->getLabel())
4340 if (existing && !existing->expired() &&
4345 .arg(ctx.
query_->getLabel())
4355 if (hasAddressReservation(ctx) &&
4363 if (!existing || existing->expired()) {
4367 .arg(ctx.
query_->getLabel())
4368 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
4378 if ((!hasAddressReservation(ctx) ||
4384 .arg(ctx.
query_->getLabel())
4396 if ((client_lease && existing) &&
4397 (client_lease->addr_ != existing->addr_) &&
4402 auto conflicted_lease = client_lease;
4403 client_lease = existing;
4420 ((hasAddressReservation(ctx) &&
4422 inAllowedPool(ctx, client_lease->addr_))) {
4426 .arg(ctx.
query_->getLabel())
4428 return (renewLease4(client_lease, ctx));
4442 .arg(ctx.
query_->getLabel())
4457 .arg(ctx.
query_->getLabel());
4462 new_lease = allocateUnreservedLease4(ctx);
4468 if (new_lease && client_lease) {
4473 .arg(ctx.
query_->getLabel())
4474 .arg(client_lease->addr_.toText());
4495 if (!classes.
empty()) {
4501 for (
auto const& name : classes) {
4503 if (cl && (!cl->getOfferLft().unspecified())) {
4504 offer_lft = cl->getOfferLft();
4512 offer_lft = ctx.
subnet_->getOfferLft();
4521 if (ctx.
query_->inClass(
"BOOTP")) {
4526 uint32_t requested_lft = 0;
4529 OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
4531 requested_lft = opt_lft->getValue();
4539 if (!classes.
empty()) {
4545 for (
auto const& name : classes) {
4547 if (cl && (!cl->getValid().unspecified())) {
4548 candidate_lft = cl->getValid();
4555 if (!candidate_lft) {
4556 candidate_lft = ctx.
subnet_->getValid();
4561 if (requested_lft > 0) {
4562 return (candidate_lft.
get(requested_lft));
4566 return (candidate_lft.
get());
4572 if (ctx.
query_->inClass(
"BOOTP")) {
4581 if (!classes.
empty()) {
4587 for (
auto const& name : classes) {
4589 if (cl && (!cl->getValid().unspecified())) {
4590 candidate_lft = cl->getValid();
4597 if (!candidate_lft) {
4598 candidate_lft = ctx.
subnet_->getValid();
4602 uint32_t remain(valid);
4605 valid = candidate_lft.
getMin();
4608 if (remain > valid) {
4616 auto const& threshold = ctx.
subnet_->getAdaptiveLeaseTimeThreshold();
4617 if (!threshold.unspecified() && (threshold < 1.0)) {
4619 getOccupancyRate(addr, ctx.
query_->getClasses());
4620 if (occupancy >= threshold) {
4629AllocEngine::createLease4(
const ClientContext4& ctx,
const IOAddress& addr,
4632 isc_throw(BadValue,
"Can't create a lease with NULL HW address");
4635 isc_throw(BadValue,
"Can't create a lease without a subnet");
4639 uint32_t valid_lft = ctx.offer_lft_;
4641 if (useMinValidLft(ctx, addr)) {
4648 time_t now = time(0);
4652 Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
4653 valid_lft, now, ctx.subnet_->getID()));
4656 lease->fqdn_fwd_ = ctx.fwd_dns_update_;
4657 lease->fqdn_rev_ = ctx.rev_dns_update_;
4658 lease->hostname_ = ctx.hostname_;
4664 if (ctx.callout_handle_ &&
4671 ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
4674 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
4678 ctx.callout_handle_->setArgument(
"query4", ctx.query_);
4685 boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
4686 ctx.callout_handle_->setArgument(
"subnet4", subnet4);
4689 ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
4692 ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
4695 ctx.callout_handle_->setArgument(
"lease4", lease);
4700 callout_status = ctx.callout_handle_->getStatus();
4712 ctx.callout_handle_->getArgument(
"lease4", lease);
4715 if (ctx.fake_allocation_ && ctx.offer_lft_) {
4719 lease->fqdn_fwd_ =
false;
4720 lease->fqdn_rev_ =
false;
4723 if (!ctx.fake_allocation_ || ctx.offer_lft_) {
4724 auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_,
false);
4726 lease->pool_id_ = pool->getID();
4735 "assigned-addresses"),
4736 static_cast<int64_t
>(1));
4740 "cumulative-assigned-addresses"),
4741 static_cast<int64_t
>(1));
4747 "assigned-addresses")),
4748 static_cast<int64_t
>(1));
4753 "cumulative-assigned-addresses")),
4754 static_cast<int64_t
>(1));
4789 time_t now = time(0);
4791 if (lease->cltt_ > now) {
4794 uint32_t age = now - lease->cltt_;
4796 if (age >= lease->valid_lft_) {
4799 valid = lease->valid_lft_ - age;
4803AllocEngine::renewLease4(
const Lease4Ptr& lease,
4813 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4818 lease->reuseable_valid_lft_ = 0;
4819 if (!updateLease4Information(lease, ctx)) {
4820 setLeaseReusable(lease, ctx);
4845 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4852 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
4886 lease->pool_id_ = pool->getID();
4896 "assigned-addresses"),
4897 static_cast<int64_t
>(1));
4901 "cumulative-assigned-addresses"),
4902 static_cast<int64_t
>(1));
4908 "assigned-addresses")),
4909 static_cast<int64_t
>(1));
4914 "cumulative-assigned-addresses")),
4915 static_cast<int64_t
>(1));
4926 *lease = *old_values;
4933AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4934 AllocEngine::ClientContext4& ctx,
4937 isc_throw(BadValue,
"null lease specified for reuseExpiredLease");
4941 isc_throw(BadValue,
"null subnet specified for the reuseExpiredLease");
4952 expired->reuseable_valid_lft_ = 0;
4953 static_cast<void>(updateLease4Information(expired, ctx));
4957 .arg(ctx.
query_->getLabel())
4958 .arg(expired->toText());
4965 ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
4982 boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
5016 expired->pool_id_ = pool->getID();
5024 "assigned-addresses"),
5025 static_cast<int64_t
>(1));
5029 "cumulative-assigned-addresses"),
5030 static_cast<int64_t
>(1));
5036 "assigned-addresses")),
5037 static_cast<int64_t
>(1));
5042 "cumulative-assigned-addresses")),
5043 static_cast<int64_t
>(1));
5060AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate,
ClientContext4& ctx,
5062 ctx.conflicting_lease_.reset();
5066 if (exist_lease->expired()) {
5067 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5071 ctx.old_lease_->hostname_.clear();
5072 ctx.old_lease_->fqdn_fwd_ =
false;
5073 ctx.old_lease_->fqdn_rev_ =
false;
5074 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
5080 ctx.conflicting_lease_ = exist_lease;
5084 return (createLease4(ctx, candidate, callout_status));
5104 ctx.subnet_->getSharedNetwork(network);
5111 ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
5125 uint64_t subnets_with_unavail_leases = 0;
5128 uint64_t subnets_with_unavail_pools = 0;
5130 auto const& classes = ctx.query_->getClasses();
5134 bool hwaddr_empty = (!ctx.hwaddr_ || ctx.hwaddr_->hwaddr_.empty());
5138 if (subnet->getMatchClientId() || hwaddr_empty) {
5139 client_id = ctx.clientid_;
5151 (attempts_ == 0 || possible_attempts < attempts_) ?
5155 if (max_attempts > 0) {
5158 ++subnets_with_unavail_leases;
5162 ++subnets_with_unavail_pools;
5165 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
5170 for (
uint128_t i = 0; i < max_attempts; ++i) {
5175 IOAddress candidate = allocator->pickAddress(classes,
5177 ctx.requested_address_);
5184 if (exclude_first_last_24) {
5186 auto const& bytes = candidate.
toBytes();
5187 if ((bytes.size() != 4) ||
5188 (bytes[3] == 0) || (bytes[3] == 255U)) {
5195 if (check_reservation_first && addressReserved(candidate, ctx)) {
5202 ResourceHandler4 resource_handler;
5204 !resource_handler.
tryLock4(candidate)) {
5213 if (check_reservation_first || !addressReserved(candidate, ctx)) {
5215 new_lease = createLease4(ctx, candidate, callout_status);
5219 if (exist_lease->expired() &&
5220 (check_reservation_first || !addressReserved(candidate, ctx))) {
5221 ctx.old_lease_ =
Lease4Ptr(
new Lease4(*exist_lease));
5225 ctx.old_lease_->hostname_.clear();
5226 ctx.old_lease_->fqdn_fwd_ =
false;
5227 ctx.old_lease_->fqdn_rev_ =
false;
5228 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
5246 subnet = subnet->getNextSubnet(original_subnet, classes);
5249 ctx.subnet_ = subnet;
5258 .arg(ctx.query_->getLabel())
5259 .arg(network->getName())
5260 .arg(subnets_with_unavail_leases)
5261 .arg(subnets_with_unavail_pools);
5263 static_cast<int64_t
>(1));
5266 "v4-allocation-fail-shared-network"),
5267 static_cast<int64_t
>(1));
5271 std::string shared_network = ctx.subnet_->getSharedNetworkName();
5272 if (shared_network.empty()) {
5273 shared_network =
"(none)";
5276 .arg(ctx.query_->getLabel())
5277 .arg(ctx.subnet_->toText())
5278 .arg(ctx.subnet_->getID())
5279 .arg(shared_network);
5281 static_cast<int64_t
>(1));
5284 "v4-allocation-fail-subnet"),
5285 static_cast<int64_t
>(1));
5287 if (total_attempts == 0) {
5293 .arg(ctx.query_->getLabel());
5295 static_cast<int64_t
>(1));
5298 "v4-allocation-fail-no-pools"),
5299 static_cast<int64_t
>(1));
5306 .arg(ctx.query_->getLabel())
5307 .arg(total_attempts);
5309 static_cast<int64_t
>(1));
5312 "v4-allocation-fail"),
5313 static_cast<int64_t
>(1));
5316 if (!classes.empty()) {
5318 .arg(ctx.query_->getLabel())
5319 .arg(classes.toText());
5321 static_cast<int64_t
>(1));
5324 "v4-allocation-fail-classes"),
5325 static_cast<int64_t
>(1));
5332AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
5333 AllocEngine::ClientContext4& ctx)
const {
5334 bool changed =
false;
5335 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
5337 lease->subnet_id_ = ctx.
subnet_->getID();
5339 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
5341 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
5347 if (!lease->client_id_ || (*clientid != *lease->client_id_)) {
5349 lease->client_id_ = clientid;
5351 }
else if (lease->client_id_) {
5355 uint32_t remain_lft(0);
5357 lease->cltt_ = time(0);
5361 if (!lease->valid_lft_) {
5362 if (useMinValidLft(ctx, lease->addr_)) {
5363 lease->valid_lft_ = remain_lft;
5371 if (lease->valid_lft_ != lease->current_valid_lft_) {
5395 bool changed =
false;
5398 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5413 sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
5422 extended_info->set(
"sub-options", relay_agent);
5426 std::vector<uint8_t> bytes = remote_id->toBinary();
5427 lease->remote_id_ = bytes;
5428 if (bytes.size() > 0) {
5429 extended_info->set(
"remote-id",
5436 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5437 lease->relay_id_ = bytes;
5438 if (bytes.size() > 0) {
5439 extended_info->set(
"relay-id",
5445 return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
5455 if (!ctx.
subnet_->getStoreExtendedInfo()) {
5460 if (ctx.
query_->relay_info_.empty()) {
5475 for (
auto const& relay : ctx.
query_->relay_info_) {
5484 if (!relay.options_.empty()) {
5489 const uint8_t* cp = buf.
getData();
5490 std::vector<uint8_t> bytes;
5491 std::stringstream ss;
5499 if (remote_id_it != relay.options_.end()) {
5500 OptionPtr remote_id = remote_id_it->second;
5502 std::vector<uint8_t> bytes = remote_id->toBinary();
5503 if (bytes.size() > 0) {
5504 relay_elem->set(
"remote-id",
5511 if (relay_id_it != relay.options_.end()) {
5512 OptionPtr relay_id = relay_id_it->second;
5514 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
5515 if (bytes.size() > 0) {
5516 relay_elem->set(
"relay-id",
5523 extended_info->add(relay_elem);
5527 if (lease->updateUserContextISC(
"relay-info", extended_info)) {
5533AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
5534 const ClientContext4& ctx)
const {
5536 lease->reuseable_valid_lft_ = 0;
5552 if (lease->cltt_ < lease->current_cltt_) {
5556 uint32_t age = lease->cltt_ - lease->current_cltt_;
5558 if (age >= lease->current_valid_lft_) {
5563 uint32_t max_age = 0;
5564 if (!subnet->getCacheMaxAge().unspecified()) {
5565 max_age = subnet->getCacheMaxAge().get();
5566 if ((max_age == 0) || (age > max_age)) {
5572 if (!subnet->getCacheThreshold().unspecified()) {
5573 double threshold = subnet->getCacheThreshold().get();
5574 if ((threshold <= 0.) || (threshold > 1.)) {
5577 max_age = lease->valid_lft_ * threshold;
5578 if (age > max_age) {
5589 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
5593AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
5594 uint32_t current_preferred_lft,
5597 lease->reuseable_valid_lft_ = 0;
5598 lease->reuseable_preferred_lft_ = 0;
5608 if (lease->cltt_ < lease->current_cltt_) {
5612 uint32_t age = lease->cltt_ - lease->current_cltt_;
5614 if (age >= lease->current_valid_lft_) {
5619 uint32_t max_age = 0;
5620 if (!subnet->getCacheMaxAge().unspecified()) {
5621 max_age = subnet->getCacheMaxAge().get();
5622 if ((max_age == 0) || (age > max_age)) {
5628 if (!subnet->getCacheThreshold().unspecified()) {
5629 double threshold = subnet->getCacheThreshold().get();
5630 if ((threshold <= 0.) || (threshold > 1.)) {
5633 max_age = lease->valid_lft_ * threshold;
5634 if (age > max_age) {
5646 (current_preferred_lft == 0)) {
5648 lease->reuseable_preferred_lft_ = current_preferred_lft;
5649 }
else if (current_preferred_lft > age) {
5650 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
5658 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 NameChangeRequest from the DHCPv4 lease and queues it to be sent to D2.
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.
ClientIdPtr getClientId() const
Returns the client identifier when the subnet match-client-id flag is true or the HW address empty.
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.
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