34 #include <boost/foreach.hpp> 35 #include <boost/make_shared.hpp> 52 namespace ph = std::placeholders;
57 struct AllocEngineHooks {
58 int hook_index_lease4_select_;
59 int hook_index_lease4_renew_;
60 int hook_index_lease4_expire_;
61 int hook_index_lease4_recover_;
62 int hook_index_lease6_select_;
63 int hook_index_lease6_renew_;
64 int hook_index_lease6_rebind_;
65 int hook_index_lease6_expire_;
66 int hook_index_lease6_recover_;
70 hook_index_lease4_select_ = HooksManager::registerHook(
"lease4_select");
71 hook_index_lease4_renew_ = HooksManager::registerHook(
"lease4_renew");
72 hook_index_lease4_expire_ = HooksManager::registerHook(
"lease4_expire");
73 hook_index_lease4_recover_= HooksManager::registerHook(
"lease4_recover");
74 hook_index_lease6_select_ = HooksManager::registerHook(
"lease6_select");
75 hook_index_lease6_renew_ = HooksManager::registerHook(
"lease6_renew");
76 hook_index_lease6_rebind_ = HooksManager::registerHook(
"lease6_rebind");
77 hook_index_lease6_expire_ = HooksManager::registerHook(
"lease6_expire");
78 hook_index_lease6_recover_= HooksManager::registerHook(
"lease6_recover");
86 AllocEngineHooks
Hooks;
93 AllocEngine::AllocEngine(uint64_t attempts)
94 : attempts_(attempts), incomplete_v4_reclamations_(0),
95 incomplete_v6_reclamations_(0) {
98 hook_index_lease4_select_ =
Hooks.hook_index_lease4_select_;
99 hook_index_lease6_select_ =
Hooks.hook_index_lease6_select_;
126 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
129 reserved.push_back(host);
133 reserved.insert(reserved.end(), hosts.begin(), hosts.end());
152 const IOAddress& address,
bool check_subnet) {
156 auto const& classes = ctx.
query_->getClasses();
158 while (current_subnet) {
159 if (current_subnet->clientSupported(classes)) {
161 if (current_subnet->inPool(lease_type, address)) {
165 if (current_subnet->inPool(lease_type, address, classes)) {
171 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
187 : query_(), fake_allocation_(false),
188 early_global_reservations_lookup_(false), subnet_(), host_subnet_(),
189 duid_(), hwaddr_(), host_identifiers_(), hosts_(),
190 fwd_dns_update_(false), rev_dns_update_(false), hostname_(),
191 callout_handle_(), ias_(), ddns_params_() {
198 const std::string& hostname,
199 const bool fake_allocation,
207 ias_(), ddns_params_() {
216 : iaid_(0), type_(
Lease::TYPE_NA), hints_(), old_leases_(),
217 changed_leases_(), new_resources_(), ia_rsp_() {
223 const uint8_t prefix_len,
224 const uint32_t preferred,
225 const uint32_t valid) {
235 addHint(iaaddr->getAddress(), 128,
236 iaaddr->getPreferred(), iaaddr->getValid());
245 addHint(iaprefix->getAddress(), iaprefix->getLength(),
246 iaprefix->getPreferred(), iaprefix->getValid());
252 const uint8_t prefix_len) {
259 const uint8_t prefix_len)
const {
267 const uint8_t prefix_len) {
275 return (static_cast<bool>
282 if (subnet && subnet->getReservationsInSubnet()) {
283 auto host =
hosts_.find(subnet->getID());
284 if (host !=
hosts_.cend()) {
285 return (host->second);
295 if (subnet &&
subnet_->getReservationsGlobal()) {
296 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
297 if (host !=
hosts_.cend()) {
298 return (host->second);
308 return (ghost && ghost->hasReservation(resv));
314 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
315 return (ddns_params_);
321 return (ddns_params_);
340 !subnet->getReservationsInSubnet()) {
346 subnet->getReservationsGlobal()) {
349 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
352 if (!subnet->getReservationsInSubnet()) {
358 std::map<SubnetID, ConstHostPtr> host_map;
360 subnet->getSharedNetwork(network);
369 const bool use_single_query = network &&
373 if (use_single_query) {
377 id_pair.second.size());
381 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
382 if ((*host)->getIPv6SubnetID() != SUBNET_ID_GLOBAL) {
383 host_map[(*host)->getIPv6SubnetID()] = *host;
389 auto const& classes = ctx.
query_->getClasses();
396 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
399 if (use_single_query) {
400 if (host_map.count(subnet->getID()) > 0) {
401 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
409 id_pair.second.size());
412 ctx.
hosts_[subnet->getID()] = host;
422 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
432 &id_pair.second[0], id_pair.second.size());
466 for (
auto l : all_leases) {
467 if ((l)->subnet_id_ == subnet->getID()) {
472 subnet = subnet->getNextSubnet(ctx.
subnet_);
492 if (leases.empty() && !ctx.
hosts_.empty()) {
496 .arg(ctx.
query_->getLabel());
501 allocateReservedLeases6(ctx, leases);
503 leases = updateLeaseData(ctx, leases);
518 }
else if (!leases.empty() && ctx.
hosts_.empty()) {
522 .arg(ctx.
query_->getLabel());
526 removeNonmatchingReservedLeases6(ctx, leases);
528 leases = updateLeaseData(ctx, leases);
537 }
else if (!leases.empty() && !ctx.
hosts_.empty()) {
541 .arg(ctx.
query_->getLabel());
545 allocateReservedLeases6(ctx, leases);
557 removeNonmatchingReservedLeases6(ctx, leases);
566 removeNonreservedLeases6(ctx, leases);
571 leases = updateLeaseData(ctx, leases);
584 if (leases.empty()) {
598 .arg(ctx.
query_->getLabel());
600 leases = allocateUnreservedLeases6(ctx);
603 if (!leases.empty()) {
618 .arg(ctx.
query_->getLabel())
631 uint8_t hint_prefix_length = 128;
644 uint64_t total_attempts = 0;
648 uint64_t subnets_with_unavail_leases = 0;
651 uint64_t subnets_with_unavail_pools = 0;
661 bool search_hint_lease =
true;
668 if (hint_prefix_length == 128) {
669 hint_prefix_length = 0;
671 if (!hint_prefix_length) {
679 Lease6Ptr lease = allocateBestMatch(ctx, hint_lease, search_hint_lease,
680 hint, hint_prefix_length, subnet,
681 network, total_attempts,
682 subnets_with_unavail_leases,
683 subnets_with_unavail_pools,
684 callout_status, prefix_length_match);
692 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
693 hint_prefix_length, subnet, network,
694 total_attempts, subnets_with_unavail_leases,
695 subnets_with_unavail_pools, callout_status,
696 prefix_length_match);
705 lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
706 hint_prefix_length, subnet, network,
707 total_attempts, subnets_with_unavail_leases,
708 subnets_with_unavail_pools, callout_status,
709 prefix_length_match);
713 leases.push_back(lease);
717 auto const& classes = ctx.
query_->getClasses();
723 .arg(ctx.
query_->getLabel())
724 .arg(network->getName())
725 .arg(subnets_with_unavail_leases)
726 .arg(subnets_with_unavail_pools);
727 StatsMgr::instance().addValue(
"v6-allocation-fail-shared-network",
728 static_cast<int64_t>(1));
729 StatsMgr::instance().addValue(
730 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
731 "v6-allocation-fail-shared-network"),
732 static_cast<int64_t>(1));
736 std::string shared_network = ctx.
subnet_->getSharedNetworkName();
737 if (shared_network.empty()) {
738 shared_network =
"(none)";
741 .arg(ctx.
query_->getLabel())
744 .arg(shared_network);
745 StatsMgr::instance().addValue(
"v6-allocation-fail-subnet",
746 static_cast<int64_t>(1));
747 StatsMgr::instance().addValue(
748 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
749 "v6-allocation-fail-subnet"),
750 static_cast<int64_t>(1));
752 if (total_attempts == 0) {
758 .arg(ctx.
query_->getLabel());
759 StatsMgr::instance().addValue(
"v6-allocation-fail-no-pools",
760 static_cast<int64_t>(1));
761 StatsMgr::instance().addValue(
762 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
763 "v6-allocation-fail-no-pools"),
764 static_cast<int64_t>(1));
771 .arg(ctx.
query_->getLabel())
772 .arg(total_attempts);
773 StatsMgr::instance().addValue(
"v6-allocation-fail",
774 static_cast<int64_t>(1));
775 StatsMgr::instance().addValue(
776 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
777 "v6-allocation-fail"),
778 static_cast<int64_t>(1));
781 if (!classes.empty()) {
783 .arg(ctx.
query_->getLabel())
784 .arg(classes.toText());
785 StatsMgr::instance().addValue(
"v6-allocation-fail-classes",
786 static_cast<int64_t>(1));
787 StatsMgr::instance().addValue(
788 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
789 "v6-allocation-fail-classes"),
790 static_cast<int64_t>(1));
800 bool& search_hint_lease,
802 uint8_t hint_prefix_length,
805 uint64_t& total_attempts,
806 uint64_t& subnets_with_unavail_leases,
807 uint64_t& subnets_with_unavail_pools,
810 auto const& classes = ctx.
query_->getClasses();
815 if (!search_hint_lease) {
816 usable_hint_lease = hint_lease;
818 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
819 if (!subnet->clientSupported(classes)) {
827 pool = boost::dynamic_pointer_cast<
Pool6>
831 if (!pool || !pool->clientSupported(classes)) {
837 hint_prefix_length)) {
841 bool in_subnet = subnet->getReservationsInSubnet();
844 if (search_hint_lease) {
845 search_hint_lease =
false;
847 usable_hint_lease = hint_lease;
849 if (!usable_hint_lease) {
861 (!subnet->getReservationsOutOfPool() ||
863 hosts = getIPv6Resrv(subnet->getID(), hint);
873 Lease6Ptr new_lease = createLease6(ctx, hint, pool->getLength(), callout_status);
886 .arg(ctx.
query_->getLabel())
890 }
else if (usable_hint_lease->expired()) {
899 (!subnet->getReservationsOutOfPool() ||
901 hosts = getIPv6Resrv(subnet->getID(), hint);
913 Lease6Ptr lease = reuseExpiredLease(usable_hint_lease, ctx,
923 .arg(ctx.
query_->getLabel())
932 bool check_reservation_first = MultiThreadingMgr::instance().getMode();
935 if (!check_reservation_first) {
949 original_subnet->getSharedNetwork(network);
956 original_subnet = network->getPreferredSubnet(original_subnet, ctx.
currentIA().
type_);
959 ctx.
subnet_ = subnet = original_subnet;
961 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
962 if (!subnet->clientSupported(classes)) {
972 uint64_t possible_attempts = subnet->getPoolCapacity(ctx.
currentIA().
type_,
982 uint64_t max_attempts = ((attempts_ == 0) || (possible_attempts < attempts_)) ? possible_attempts : attempts_;
984 if (max_attempts > 0) {
987 ++subnets_with_unavail_leases;
991 ++subnets_with_unavail_pools;
995 bool in_subnet = subnet->getReservationsInSubnet();
996 bool out_of_pool = subnet->getReservationsOutOfPool();
1005 for (uint64_t i = 0; i < max_attempts; ++i) {
1013 uint8_t prefix_len = 128;
1015 candidate = allocator->pickPrefix(classes, pool, ctx.
duid_,
1016 prefix_length_match, hint,
1017 hint_prefix_length);
1019 prefix_len = pool->getLength();
1022 candidate = allocator->pickAddress(classes, ctx.
duid_, hint);
1026 if (check_reservation_first && in_subnet && !out_of_pool) {
1027 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1028 if (!hosts.empty()) {
1037 if (MultiThreadingMgr::instance().getMode() &&
1051 if (!check_reservation_first && in_subnet && !out_of_pool) {
1052 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1053 if (!hosts.empty()) {
1063 Lease6Ptr new_lease = createLease6(ctx, candidate, prefix_len, callout_status);
1072 (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
1080 }
else if (existing->expired()) {
1082 if (!check_reservation_first && in_subnet && !out_of_pool) {
1083 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1084 if (!hosts.empty()) {
1096 existing = reuseExpiredLease(existing, ctx, prefix_len,
1111 if (ctx.
hosts_.empty()) {
1114 .arg(ctx.
query_->getLabel());
1125 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1126 if ((lease->valid_lft_ != 0)) {
1127 if ((ctx.
hosts_.count(lease->subnet_id_) > 0) &&
1133 .arg(ctx.
query_->getLabel())
1134 .arg(lease->typeToText(lease->type_))
1135 .arg(lease->addr_.toText());
1143 ctx.
subnet_->getSharedNetwork(network);
1148 ctx.
host_subnet_ = network->getSubnet(lease->subnet_id_);
1156 if (host && !host->getHostname().empty()) {
1164 static_cast<bool>(fqdn));
1178 auto const& classes = ctx.
query_->getClasses();
1180 subnet = subnet->getNextSubnet(ctx.
subnet_)) {
1182 SubnetID subnet_id = subnet->getID();
1185 if (!subnet->clientSupported(classes) || ctx.
hosts_.count(subnet_id) == 0) {
1191 bool in_subnet = subnet->getReservationsInSubnet();
1197 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1198 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1211 (subnet->getReservationsOutOfPool() &&
1228 if (!host->getHostname().empty()) {
1243 static_cast<bool>(fqdn));
1249 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1252 existing_leases.push_back(lease);
1257 .arg(ctx.
query_->getLabel());
1261 .arg(static_cast<int>(prefix_len))
1262 .arg(ctx.
query_->getLabel());
1280 allocateGlobalReservedLeases6(ctx, existing_leases);
1295 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1296 if ((lease->valid_lft_ != 0) &&
1302 .arg(ctx.
query_->getLabel())
1303 .arg(lease->typeToText(lease->type_))
1304 .arg(lease->addr_.toText());
1310 if (!ghost->getHostname().empty()) {
1318 static_cast<bool>(fqdn));
1333 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1336 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1337 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1353 bool valid_subnet =
false;
1356 if (subnet->inRange(addr)) {
1357 valid_subnet =
true;
1361 subnet = subnet->getNextSubnet(ctx.
subnet_);
1364 if (!valid_subnet) {
1375 if (!ghost->getHostname().empty()) {
1390 static_cast<bool>(fqdn));
1395 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1398 existing_leases.push_back(lease);
1403 .arg(ctx.
query_->getLabel());
1407 .arg(static_cast<int>(prefix_len))
1408 .arg(ctx.
query_->getLabel());
1426 AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1429 if (existing_leases.empty() || !ctx.
subnet_) {
1434 if (!ctx.
subnet_->getReservationsInSubnet() &&
1435 !ctx.
subnet_->getReservationsGlobal()) {
1436 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1445 BOOST_FOREACH(
const Lease6Ptr& candidate, copy) {
1450 ((ctx.
hosts_.count(candidate->subnet_id_) > 0) &&
1451 (ctx.
hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1460 auto hosts = getIPv6Resrv(ctx.
subnet_->getID(), candidate->addr_);
1465 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1466 candidate->addr_,
false)) {
1470 if (!hosts.empty()) {
1473 if (hosts.size() == 1) {
1476 .arg(candidate->addr_.toText())
1477 .arg(ctx.
duid_->toText())
1478 .arg(hosts.front()->getIdentifierAsText());
1481 .arg(candidate->addr_.toText())
1482 .arg(static_cast<int>(candidate->prefixlen_))
1483 .arg(ctx.
duid_->toText())
1484 .arg(hosts.front()->getIdentifierAsText());
1489 .arg(candidate->addr_.toText())
1490 .arg(ctx.
duid_->toText())
1494 .arg(candidate->addr_.toText())
1495 .arg(static_cast<int>(candidate->prefixlen_))
1496 .arg(ctx.
duid_->toText())
1514 StatsMgr::instance().addValue(
1515 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1517 "assigned-nas" :
"assigned-pds"),
1518 static_cast<int64_t>(-1));
1529 removeLeases(existing_leases, candidate->addr_);
1534 AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1541 BOOST_FOREACH(
const Lease6Ptr& candidate, copy) {
1545 if (inAllowedPool(ctx, candidate->type_,
1546 candidate->addr_,
false)) {
1561 StatsMgr::instance().addValue(
1562 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1564 "assigned-nas" :
"assigned-pds"),
1565 static_cast<int64_t>(-1));
1571 removeLeases(existing_leases, candidate->addr_);
1578 bool removed =
false;
1579 for (Lease6Collection::iterator lease = container.begin();
1580 lease != container.end(); ++lease) {
1581 if ((*lease)->addr_ == addr) {
1588 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1599 int total = existing_leases.size();
1606 for (Lease6Collection::iterator lease = existing_leases.begin();
1607 lease != existing_leases.end(); ++lease) {
1612 ((ctx.
hosts_.count((*lease)->subnet_id_) > 0) &&
1613 (ctx.
hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1632 StatsMgr::instance().addValue(
1633 StatsMgr::generateName(
"subnet", (*lease)->subnet_id_,
1635 "assigned-nas" :
"assigned-pds"),
1636 static_cast<int64_t>(-1));
1656 existing_leases.erase(std::remove(existing_leases.begin(),
1657 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1665 if (!expired->expired()) {
1682 expired->duid_ = ctx.
duid_;
1685 getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
1686 expired->reuseable_valid_lft_ = 0;
1688 expired->cltt_ = time(NULL);
1689 expired->subnet_id_ = ctx.
subnet_->getID();
1693 expired->prefixlen_ = prefix_len;
1698 .arg(ctx.
query_->getLabel())
1699 .arg(expired->toText());
1703 HooksManager::calloutsPresent(hook_index_lease6_select_)) {
1729 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.
callout_handle_);
1736 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
1761 StatsMgr::instance().addValue(
1762 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1764 "assigned-nas" :
"assigned-pds"),
1765 static_cast<int64_t>(1));
1766 StatsMgr::instance().addValue(
1767 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1769 "cumulative-assigned-nas" :
1770 "cumulative-assigned-pds"),
1771 static_cast<int64_t>(1));
1773 "cumulative-assigned-nas" :
1774 "cumulative-assigned-pds",
1775 static_cast<int64_t
>(1));
1794 if (!classes.
empty()) {
1801 for (
auto name = classes.
cbegin();
1802 name != classes.
cend() && have_both < 2; ++name) {
1805 (cl && (!cl->getPreferred().unspecified()))) {
1806 candidate_preferred = cl->getPreferred();
1811 (cl && (!cl->getValid().unspecified()))) {
1812 candidate_valid = cl->getValid();
1819 if (!candidate_preferred) {
1820 candidate_preferred = ctx.
subnet_->getPreferred();
1824 if (!candidate_valid) {
1825 candidate_valid = ctx.
subnet_->getValid();
1829 preferred = candidate_preferred;
1830 valid = candidate_valid;
1854 uint32_t preferred = 0;
1869 HooksManager::calloutsPresent(hook_index_lease6_select_)) {
1895 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.
callout_handle_);
1902 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
1923 StatsMgr::instance().addValue(
1924 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1926 "assigned-nas" :
"assigned-pds"),
1927 static_cast<int64_t>(1));
1928 StatsMgr::instance().addValue(
1929 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1931 "cumulative-assigned-nas" :
1932 "cumulative-assigned-pds"),
1933 static_cast<int64_t>(1));
1935 "cumulative-assigned-nas" :
1936 "cumulative-assigned-pds",
1937 static_cast<int64_t
>(1));
1980 leases.insert(leases.end(), leases_subnet.begin(), leases_subnet.end());
1982 subnet = subnet->getNextSubnet(ctx.
subnet_);
1985 if (!leases.empty()) {
1988 .arg(ctx.
query_->getLabel());
1992 removeNonmatchingReservedLeases6(ctx, leases);
1995 if (!ctx.
hosts_.empty()) {
1999 .arg(ctx.
query_->getLabel());
2002 allocateReservedLeases6(ctx, leases);
2008 removeNonreservedLeases6(ctx, leases);
2015 if (leases.empty()) {
2019 .arg(ctx.
query_->getLabel());
2021 leases = allocateUnreservedLeases6(ctx);
2025 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2027 (*l)->prefixlen_)) {
2033 .arg(ctx.
query_->getLabel())
2034 .arg((*l)->typeToText((*l)->type_))
2036 extendLease6(ctx, *l);
2039 if (!leases.empty()) {
2043 BOOST_FOREACH(
Lease6Ptr lease, leases) {
2055 .arg(ctx.
query_->getLabel())
2071 if (ctx.
subnet_->getID() != lease->subnet_id_) {
2073 ctx.
subnet_->getSharedNetwork(network);
2102 StatsMgr::instance().addValue(
2103 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
"assigned-nas"),
2104 static_cast<int64_t>(-1));
2114 .arg(ctx.
query_->getLabel())
2115 .arg(lease->toText());
2120 bool changed =
false;
2123 uint32_t current_preferred_lft = lease->preferred_lft_;
2124 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2127 if ((lease->preferred_lft_ != current_preferred_lft) ||
2128 (lease->valid_lft_ != lease->current_valid_lft_)) {
2132 lease->cltt_ = time(NULL);
2141 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
2143 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
2153 .arg(ctx.
query_->getLabel())
2154 .arg(lease->toText());
2159 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2160 if (HooksManager::calloutsPresent(hook_point)) {
2173 callout_handle->setArgument(
"query6", ctx.
query_);
2176 callout_handle->setArgument(
"lease6", lease);
2186 HooksManager::callCallouts(hook_point, *callout_handle);
2191 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2195 .arg(ctx.
query_->getName());
2202 bool update_stats =
false;
2206 if (old_data->expired()) {
2212 update_stats =
true;
2225 setLeaseReusable(lease, current_preferred_lft, ctx);
2230 if (lease->reuseable_valid_lft_ == 0) {
2235 StatsMgr::instance().addValue(
2236 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2238 "assigned-nas" :
"assigned-pds"),
2239 static_cast<int64_t>(1));
2240 StatsMgr::instance().addValue(
2241 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2243 "cumulative-assigned-nas" :
2244 "cumulative-assigned-pds"),
2245 static_cast<int64_t>(1));
2247 "cumulative-assigned-nas" :
2248 "cumulative-assigned-pds",
2249 static_cast<int64_t
>(1));
2268 for (Lease6Collection::const_iterator lease_it = leases.begin();
2269 lease_it != leases.end(); ++lease_it) {
2273 updated_leases.push_back(lease);
2277 lease->reuseable_valid_lft_ = 0;
2281 uint32_t current_preferred_lft = lease->preferred_lft_;
2282 if (lease->valid_lft_ == 0) {
2284 getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
2287 bool update_stats =
false;
2296 lease->addr_,
true)) {
2297 update_stats =
true;
2302 !(lease->hasIdenticalFqdn(**lease_it)));
2304 lease->cltt_ = time(NULL);
2305 if (!fqdn_changed) {
2306 setLeaseReusable(lease, current_preferred_lft, ctx);
2308 if (lease->reuseable_valid_lft_ == 0) {
2314 StatsMgr::instance().addValue(
2315 StatsMgr::generateName(
"subnet", lease->subnet_id_,
2317 "assigned-nas" :
"assigned-pds"),
2318 static_cast<int64_t>(1));
2319 StatsMgr::instance().addValue(
2320 StatsMgr::generateName(
"subnet", lease->subnet_id_,
2322 "cumulative-assigned-nas" :
2323 "cumulative-assigned-pds"),
2324 static_cast<int64_t>(1));
2326 "cumulative-assigned-nas" :
2327 "cumulative-assigned-pds",
2328 static_cast<int64_t
>(1));
2332 updated_leases.push_back(lease);
2335 return (updated_leases);
2340 const uint16_t timeout,
2341 const bool remove_lease,
2342 const uint16_t max_unwarned_cycles) {
2351 max_unwarned_cycles);
2352 }
catch (
const std::exception& ex) {
2361 const uint16_t timeout,
2362 const bool remove_lease,
2363 const uint16_t max_unwarned_cycles) {
2373 bool incomplete_reclamation =
false;
2376 if (max_leases > 0) {
2385 if (leases.size() > max_leases) {
2387 incomplete_reclamation =
true;
2400 if (!leases.empty() &&
2401 HooksManager::calloutsPresent(
Hooks.hook_index_lease6_expire_)) {
2402 callout_handle = HooksManager::createCalloutHandle();
2405 size_t leases_processed = 0;
2406 BOOST_FOREACH(
Lease6Ptr lease, leases) {
2410 if (MultiThreadingMgr::instance().getMode()) {
2414 reclaimExpiredLease(lease, remove_lease, callout_handle);
2417 reclaimExpiredLease(lease, remove_lease, callout_handle);
2421 }
catch (
const std::exception& ex) {
2423 .arg(lease->addr_.toText())
2434 if (!incomplete_reclamation) {
2435 if (leases_processed < leases.size()) {
2436 incomplete_reclamation =
true;
2453 .arg(leases_processed)
2458 if (incomplete_reclamation) {
2459 ++incomplete_v6_reclamations_;
2462 if ((max_unwarned_cycles > 0) &&
2463 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2465 .arg(max_unwarned_cycles);
2467 incomplete_v6_reclamations_ = 0;
2472 incomplete_v6_reclamations_ = 0;
2485 uint64_t deleted_leases = 0;
2491 }
catch (
const std::exception& ex) {
2498 .arg(deleted_leases);
2503 const uint16_t timeout,
2504 const bool remove_lease,
2505 const uint16_t max_unwarned_cycles) {
2514 max_unwarned_cycles);
2515 }
catch (
const std::exception& ex) {
2524 const uint16_t timeout,
2525 const bool remove_lease,
2526 const uint16_t max_unwarned_cycles) {
2536 bool incomplete_reclamation =
false;
2539 if (max_leases > 0) {
2548 if (leases.size() > max_leases) {
2550 incomplete_reclamation =
true;
2563 if (!leases.empty() &&
2564 HooksManager::calloutsPresent(
Hooks.hook_index_lease4_expire_)) {
2565 callout_handle = HooksManager::createCalloutHandle();
2568 size_t leases_processed = 0;
2569 BOOST_FOREACH(
Lease4Ptr lease, leases) {
2573 if (MultiThreadingMgr::instance().getMode()) {
2577 reclaimExpiredLease(lease, remove_lease, callout_handle);
2580 reclaimExpiredLease(lease, remove_lease, callout_handle);
2584 }
catch (
const std::exception& ex) {
2586 .arg(lease->addr_.toText())
2597 if (!incomplete_reclamation) {
2598 if (leases_processed < leases.size()) {
2599 incomplete_reclamation =
true;
2616 .arg(leases_processed)
2621 if (incomplete_reclamation) {
2622 ++incomplete_v4_reclamations_;
2625 if ((max_unwarned_cycles > 0) &&
2626 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
2628 .arg(max_unwarned_cycles);
2630 incomplete_v4_reclamations_ = 0;
2635 incomplete_v4_reclamations_ = 0;
2642 template<
typename LeasePtrType>
2644 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
2646 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
2650 template<
typename LeasePtrType>
2652 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
2657 if (!lease->stateExpiredReclaimed()) {
2658 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
2663 AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
2664 const DbReclaimMode& reclaim_mode,
2670 .arg(lease->addr_.toText())
2671 .arg(static_cast<int>(lease->prefixlen_));
2677 bool skipped =
false;
2678 if (callout_handle) {
2686 callout_handle->deleteAllArguments();
2687 callout_handle->setArgument(
"lease6", lease);
2688 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2690 HooksManager::callCallouts(
Hooks.hook_index_lease6_expire_,
2693 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2708 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2718 remove_lease = reclaimDeclined(lease);
2721 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2725 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
2727 &lease_mgr, ph::_1));
2736 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2743 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2751 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2754 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2756 "reclaimed-leases"),
2761 AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
2762 const DbReclaimMode& reclaim_mode,
2768 .arg(lease->addr_.toText());
2774 bool skipped =
false;
2775 if (callout_handle) {
2783 callout_handle->setArgument(
"lease4", lease);
2784 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2786 HooksManager::callCallouts(
Hooks.hook_index_lease4_expire_,
2789 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2802 lease->hostname_.clear();
2803 lease->fqdn_fwd_ =
false;
2804 lease->fqdn_rev_ =
false;
2808 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2818 remove_lease = reclaimDeclined(lease);
2821 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2825 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
2827 &lease_mgr, ph::_1));
2834 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2836 "assigned-addresses"),
2840 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2843 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2845 "reclaimed-leases"),
2855 uint64_t deleted_leases = 0;
2861 }
catch (
const std::exception& ex) {
2868 .arg(deleted_leases);
2872 AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
2877 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_recover_)) {
2887 callout_handle->setArgument(
"lease4", lease);
2890 HooksManager::callCallouts(
Hooks.hook_index_lease4_recover_, *callout_handle);
2895 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2897 .arg(lease->addr_.toText());
2903 .arg(lease->addr_.toText())
2904 .arg(lease->valid_lft_);
2906 StatsMgr& stats_mgr = StatsMgr::instance();
2909 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2910 "declined-addresses"), static_cast<int64_t>(-1));
2913 stats_mgr.
addValue(
"declined-addresses", static_cast<int64_t>(-1));
2915 stats_mgr.
addValue(
"reclaimed-declined-addresses", static_cast<int64_t>(1));
2917 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2918 "reclaimed-declined-addresses"), static_cast<int64_t>(1));
2926 AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
2931 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_recover_)) {
2941 callout_handle->setArgument(
"lease6", lease);
2944 HooksManager::callCallouts(
Hooks.hook_index_lease6_recover_, *callout_handle);
2949 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2951 .arg(lease->addr_.toText());
2957 .arg(lease->addr_.toText())
2958 .arg(lease->valid_lft_);
2960 StatsMgr& stats_mgr = StatsMgr::instance();
2963 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2964 "declined-addresses"), static_cast<int64_t>(-1));
2967 stats_mgr.
addValue(
"declined-addresses", static_cast<int64_t>(-1));
2969 stats_mgr.
addValue(
"reclaimed-declined-addresses", static_cast<int64_t>(1));
2971 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
2972 "reclaimed-declined-addresses"), static_cast<int64_t>(1));
2982 lease->relay_id_.clear();
2983 lease->remote_id_.clear();
2984 if (lease->getContext()) {
2991 if (lease->getContext()) {
2997 template<
typename LeasePtrType>
2998 void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
2999 const bool remove_lease,
3000 const std::function<
void (
const LeasePtrType&)>&
3001 lease_update_fun)
const {
3009 }
else if (lease_update_fun) {
3012 lease->reuseable_valid_lft_ = 0;
3013 lease->hostname_.clear();
3014 lease->fqdn_fwd_ =
false;
3015 lease->fqdn_rev_ =
false;
3018 lease_update_fun(lease);
3027 .arg(lease->addr_.toText());
3033 return(
"<empty subnet>");
3037 subnet->getSharedNetwork(network);
3038 std::ostringstream ss;
3040 ss <<
"shared-network: " << network->getName();
3042 ss <<
"subnet id: " << subnet->getID();
3082 (!ctx.
subnet_->getReservationsOutOfPool() ||
3097 hosts.push_back(host);
3104 for (
auto host : hosts) {
3108 if (id_pair.first == host->getIdentifierType() &&
3109 id_pair.second == host->getIdentifier()) {
3117 return (!hosts.empty());
3139 if (ctx.
hosts_.empty()) {
3144 auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3145 auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
3146 global_host->second->getIPv4Reservation() :
3155 if (subnet->getReservationsGlobal() &&
3157 (subnet->inRange(global_host_address))) {
3162 if (subnet->getReservationsInSubnet()) {
3163 auto host = ctx.
hosts_.find(subnet->getID());
3168 if (host != ctx.
hosts_.end() && host->second) {
3169 auto reservation = host->second->getIPv4Reservation();
3170 if (!reservation.isV4Zero() &&
3171 (!subnet->getReservationsOutOfPool() ||
3181 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3187 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3214 auto const& classes = ctx.
query_->getClasses();
3218 bool try_clientid_lookup = (ctx.
clientid_ &&
3222 if (try_clientid_lookup) {
3230 for (
Subnet4Ptr subnet = original_subnet; subnet;
3231 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3236 if (subnet->getMatchClientId()) {
3237 for (
auto l = leases_client_id.begin(); l != leases_client_id.end(); ++l) {
3238 if ((*l)->subnet_id_ == subnet->getID()) {
3240 client_lease = (*l);
3251 if (!client_lease && ctx.
hwaddr_) {
3256 for (
Subnet4Ptr subnet = original_subnet; subnet;
3257 subnet = subnet->getNextSubnet(original_subnet, classes)) {
3259 if (subnet->getMatchClientId()) {
3265 for (Lease4Collection::const_iterator client_lease_it = leases_hw_address.begin();
3266 client_lease_it != leases_hw_address.end(); ++client_lease_it) {
3267 Lease4Ptr existing_lease = *client_lease_it;
3268 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3269 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3271 client_lease = existing_lease;
3299 auto const& classes = ctx.
query_->getClasses();
3301 while (current_subnet) {
3310 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
3324 requested_address_(
IOAddress::IPV4_ZERO_ADDRESS()),
3327 old_lease_(), new_lease_(),
hosts_(), conflicting_lease_(),
3336 const bool fwd_dns_update,
3337 const bool rev_dns_update,
3338 const std::string& hostname,
3339 const bool fake_allocation)
3359 if (host !=
hosts_.cend()) {
3360 return (host->second);
3370 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3371 if (host !=
hosts_.cend()) {
3372 return (host->second);
3382 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3383 return (ddns_params_);
3389 return (ddns_params_);
3411 auto const& classes = ctx.
query_->getClasses();
3412 if (subnet && !subnet->clientSupported(classes)) {
3413 ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
3426 return (discoverLease4(ctx));
3435 .arg(ctx.
query_->getLabel())
3453 !subnet->getReservationsInSubnet()) {
3459 subnet->getReservationsGlobal()) {
3462 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3465 if (!subnet->getReservationsInSubnet()) {
3471 std::map<SubnetID, ConstHostPtr> host_map;
3473 subnet->getSharedNetwork(network);
3482 const bool use_single_query = network &&
3486 if (use_single_query) {
3490 id_pair.second.size());
3494 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
3495 if ((*host)->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
3496 host_map[(*host)->getIPv4SubnetID()] = *host;
3502 auto const& classes = ctx.
query_->getClasses();
3508 if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
3511 if (use_single_query) {
3512 if (host_map.count(subnet->getID()) > 0) {
3513 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
3521 id_pair.second.size());
3524 ctx.
hosts_[subnet->getID()] = host;
3534 subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
3544 &id_pair.second[0], id_pair.second.size());
3561 findClientLease(ctx, client_lease);
3571 if (hasAddressReservation(ctx)) {
3575 .arg(ctx.
query_->getLabel())
3576 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
3582 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
3589 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
3593 .arg(ctx.
query_->getLabel())
3594 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3597 StatsMgr::instance().addValue(StatsMgr::generateName(
3600 "v4-reservation-conflicts"),
3601 static_cast<int64_t>(1));
3602 StatsMgr::instance().addValue(
"v4-reservation-conflicts",
3603 static_cast<int64_t>(1));
3607 new_lease = renewLease4(client_lease, ctx);
3620 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
3621 !addressReserved(client_lease->addr_, ctx)) {
3625 .arg(ctx.
query_->getLabel());
3627 new_lease = renewLease4(client_lease, ctx);
3644 .arg(ctx.
query_->getLabel());
3657 .arg(ctx.
query_->getLabel());
3659 new_lease = allocateUnreservedLease4(ctx);
3679 findClientLease(ctx, client_lease);
3695 .arg(ctx.
query_->getLabel())
3701 }
else if (hasAddressReservation(ctx)) {
3710 .arg(ctx.
query_->getLabel())
3722 if (existing && !existing->expired() &&
3723 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
3728 .arg(ctx.
query_->getLabel())
3738 if (hasAddressReservation(ctx) &&
3746 if (!existing || existing->expired()) {
3750 .arg(ctx.
query_->getLabel())
3751 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3761 if ((!hasAddressReservation(ctx) ||
3767 .arg(ctx.
query_->getLabel())
3787 ((hasAddressReservation(ctx) &&
3789 inAllowedPool(ctx, client_lease->addr_))) {
3793 .arg(ctx.
query_->getLabel())
3796 return (renewLease4(client_lease, ctx));
3810 .arg(ctx.
query_->getLabel())
3826 .arg(ctx.
query_->getLabel());
3831 new_lease = allocateUnreservedLease4(ctx);
3837 if (new_lease && client_lease) {
3842 .arg(ctx.
query_->getLabel())
3843 .arg(client_lease->addr_.toText());
3847 StatsMgr::instance().addValue(
3848 StatsMgr::generateName(
"subnet", client_lease->subnet_id_,
3849 "assigned-addresses"),
3850 static_cast<int64_t>(-1));
3863 if (ctx.
query_->inClass(
"BOOTP")) {
3868 uint32_t requested_lft = 0;
3873 requested_lft = opt_lft->
getValue();
3881 if (!classes.
empty()) {
3888 name != classes.
cend(); ++name) {
3890 if (cl && (!cl->getValid().unspecified())) {
3891 candidate_lft = cl->getValid();
3898 if (!candidate_lft) {
3899 candidate_lft = ctx.
subnet_->getValid();
3904 if (requested_lft > 0) {
3905 return (candidate_lft.
get(requested_lft));
3909 return (candidate_lft.
get());
3925 time_t now = time(NULL);
3928 if (ctx.
subnet_->getMatchClientId()) {
3933 valid_lft, now, ctx.
subnet_->getID()));
3945 HooksManager::calloutsPresent(hook_index_lease4_select_)) {
3974 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.
callout_handle_);
3981 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
3997 StatsMgr::instance().addValue(
3998 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
3999 "assigned-addresses"),
4000 static_cast<int64_t>(1));
4001 StatsMgr::instance().addValue(
4002 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4003 "cumulative-assigned-addresses"),
4004 static_cast<int64_t>(1));
4005 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4006 static_cast<int64_t>(1));
4026 AllocEngine::renewLease4(
const Lease4Ptr& lease,
4036 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4041 lease->reuseable_valid_lft_ = 0;
4042 if (!updateLease4Information(lease, ctx)) {
4043 setLeaseReusable(lease, ctx);
4059 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_renew_)) {
4083 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4091 HooksManager::callCallouts(
Hooks.hook_index_lease4_renew_,
4097 if (ctx.
callout_handle_->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
4106 if (!ctx.
fake_allocation_ && !skip && (lease->reuseable_valid_lft_ == 0)) {
4112 StatsMgr::instance().addValue(
4113 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4114 "assigned-addresses"),
4115 static_cast<int64_t>(1));
4116 StatsMgr::instance().addValue(
4117 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4118 "cumulative-assigned-addresses"),
4119 static_cast<int64_t>(1));
4120 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4121 static_cast<int64_t>(1));
4127 *lease = *old_values;
4134 AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4153 expired->reuseable_valid_lft_ = 0;
4154 static_cast<void>(updateLease4Information(expired, ctx));
4158 .arg(ctx.
query_->getLabel())
4159 .arg(expired->toText());
4163 HooksManager::calloutsPresent(hook_index_lease4_select_)) {
4192 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.
callout_handle_);
4199 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
4217 StatsMgr::instance().addValue(
4218 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4219 "assigned-addresses"),
4220 static_cast<int64_t>(1));
4221 StatsMgr::instance().addValue(
4222 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4223 "cumulative-assigned-addresses"),
4224 static_cast<int64_t>(1));
4225 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4226 static_cast<int64_t>(1));
4244 if (exist_lease->expired()) {
4252 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
4262 return (createLease4(ctx, candidate, callout_status));
4282 ctx.
subnet_->getSharedNetwork(network);
4295 bool check_reservation_first = MultiThreadingMgr::instance().getMode();
4299 uint64_t total_attempts = 0;
4303 uint64_t subnets_with_unavail_leases = 0;
4306 uint64_t subnets_with_unavail_pools = 0;
4308 auto const& classes = ctx.
query_->getClasses();
4312 if (subnet->getMatchClientId()) {
4316 uint64_t possible_attempts =
4324 uint64_t max_attempts = ((attempts_ == 0 || possible_attempts < attempts_) ? possible_attempts : attempts_);
4326 if (max_attempts > 0) {
4329 ++subnets_with_unavail_leases;
4333 ++subnets_with_unavail_pools;
4336 bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
4341 for (uint64_t i = 0; i < max_attempts; ++i) {
4346 IOAddress candidate = allocator->pickAddress(classes,
4350 if (exclude_first_last_24) {
4352 auto const& bytes = candidate.
toBytes();
4353 if ((bytes.size() != 4) ||
4354 (bytes[3] == 0) || (bytes[3] == 255U)) {
4361 if (check_reservation_first && addressReserved(candidate, ctx)) {
4369 if (MultiThreadingMgr::instance().getMode() &&
4370 !resource_handler.
tryLock4(candidate)) {
4379 if (check_reservation_first || !addressReserved(candidate, ctx)) {
4381 new_lease = createLease4(ctx, candidate, callout_status);
4385 if (exist_lease->expired() &&
4386 (check_reservation_first || !addressReserved(candidate, ctx))) {
4388 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
4397 if (ctx.
callout_handle_ && (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
4406 subnet = subnet->getNextSubnet(original_subnet, classes);
4418 .arg(ctx.
query_->getLabel())
4419 .arg(network->getName())
4420 .arg(subnets_with_unavail_leases)
4421 .arg(subnets_with_unavail_pools);
4422 StatsMgr::instance().addValue(
"v4-allocation-fail-shared-network",
4423 static_cast<int64_t>(1));
4424 StatsMgr::instance().addValue(
4425 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4426 "v4-allocation-fail-shared-network"),
4427 static_cast<int64_t>(1));
4431 std::string shared_network = ctx.
subnet_->getSharedNetworkName();
4432 if (shared_network.empty()) {
4433 shared_network =
"(none)";
4436 .arg(ctx.
query_->getLabel())
4439 .arg(shared_network);
4440 StatsMgr::instance().addValue(
"v4-allocation-fail-subnet",
4441 static_cast<int64_t>(1));
4442 StatsMgr::instance().addValue(
4443 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4444 "v4-allocation-fail-subnet"),
4445 static_cast<int64_t>(1));
4447 if (total_attempts == 0) {
4453 .arg(ctx.
query_->getLabel());
4454 StatsMgr::instance().addValue(
"v4-allocation-fail-no-pools",
4455 static_cast<int64_t>(1));
4456 StatsMgr::instance().addValue(
4457 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4458 "v4-allocation-fail-no-pools"),
4459 static_cast<int64_t>(1));
4466 .arg(ctx.
query_->getLabel())
4467 .arg(total_attempts);
4468 StatsMgr::instance().addValue(
"v4-allocation-fail",
4469 static_cast<int64_t>(1));
4470 StatsMgr::instance().addValue(
4471 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4472 "v4-allocation-fail"),
4473 static_cast<int64_t>(1));
4476 if (!classes.empty()) {
4478 .arg(ctx.
query_->getLabel())
4479 .arg(classes.toText());
4480 StatsMgr::instance().addValue(
"v4-allocation-fail-classes",
4481 static_cast<int64_t>(1));
4482 StatsMgr::instance().addValue(
4483 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4484 "v4-allocation-fail-classes"),
4485 static_cast<int64_t>(1));
4492 AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
4494 bool changed =
false;
4495 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
4497 lease->subnet_id_ = ctx.
subnet_->getID();
4499 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
4501 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
4506 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
4510 }
else if (lease->client_id_) {
4514 lease->cltt_ = time(NULL);
4520 if (lease->valid_lft_ < lease->current_valid_lft_) {
4544 bool changed =
false;
4547 if (!ctx.
subnet_->getStoreExtendedInfo()) {
4563 extended_info->set(
"sub-options", relay_agent);
4567 std::vector<uint8_t> bytes = remote_id->toBinary(
false);
4568 lease->remote_id_ = bytes;
4569 if (bytes.size() > 0) {
4570 extended_info->set(
"remote-id",
4577 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
4578 lease->relay_id_ = bytes;
4579 if (bytes.size() > 0) {
4580 extended_info->set(
"relay-id",
4588 if (user_context && (user_context->getType() ==
Element::map)) {
4589 mutable_user_context =
copy(user_context, 0);
4598 mutable_isc =
copy(isc, 0);
4604 ConstElementPtr old_extended_info = mutable_isc->get(
"relay-agent-info");
4605 if (!old_extended_info || (*old_extended_info != *extended_info)) {
4607 mutable_isc->set(
"relay-agent-info", extended_info);
4608 mutable_user_context->set(
"ISC", mutable_isc);
4612 lease->setContext(mutable_user_context);
4624 if (!ctx.
subnet_->getStoreExtendedInfo()) {
4629 if (ctx.
query_->relay_info_.empty()) {
4644 for (
auto relay : ctx.
query_->relay_info_) {
4653 if (!relay.options_.empty()) {
4658 const uint8_t* cp =
static_cast<const uint8_t*
>(buf.
getData());
4659 std::vector<uint8_t> bytes;
4660 std::stringstream ss;
4668 if (remote_id_it != relay.options_.end()) {
4669 OptionPtr remote_id = remote_id_it->second;
4671 std::vector<uint8_t> bytes = remote_id->toBinary(
false);
4672 if (bytes.size() > 0) {
4673 relay_elem->set(
"remote-id",
4680 if (relay_id_it != relay.options_.end()) {
4681 OptionPtr relay_id = relay_id_it->second;
4683 std::vector<uint8_t> bytes = relay_id->toBinary(
false);
4684 if (bytes.size() > 0) {
4685 relay_elem->set(
"relay-id",
4692 extended_info->add(relay_elem);
4698 if (user_context && (user_context->getType() ==
Element::map)) {
4699 mutable_user_context =
copy(user_context, 0);
4708 mutable_isc =
copy(isc, 0);
4715 if (!old_extended_info || (*old_extended_info != *extended_info)) {
4717 mutable_isc->set(
"relay-info", extended_info);
4718 mutable_user_context->set(
"ISC", mutable_isc);
4722 lease->setContext(mutable_user_context);
4726 AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
4729 lease->reuseable_valid_lft_ = 0;
4745 if (lease->cltt_ < lease->current_cltt_) {
4749 uint32_t age = lease->cltt_ - lease->current_cltt_;
4751 if (age >= lease->current_valid_lft_) {
4756 uint32_t max_age = 0;
4757 if (!subnet->getCacheMaxAge().unspecified()) {
4758 max_age = subnet->getCacheMaxAge().get();
4759 if ((max_age == 0) || (age > max_age)) {
4765 if (!subnet->getCacheThreshold().unspecified()) {
4766 double threshold = subnet->getCacheThreshold().get();
4767 if ((threshold <= 0.) || (threshold > 1.)) {
4770 max_age = lease->valid_lft_ * threshold;
4771 if (age > max_age) {
4782 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
4786 AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
4787 uint32_t current_preferred_lft,
4790 lease->reuseable_valid_lft_ = 0;
4791 lease->reuseable_preferred_lft_ = 0;
4801 if (lease->cltt_ < lease->current_cltt_) {
4805 uint32_t age = lease->cltt_ - lease->current_cltt_;
4807 if (age >= lease->current_valid_lft_) {
4812 uint32_t max_age = 0;
4813 if (!subnet->getCacheMaxAge().unspecified()) {
4814 max_age = subnet->getCacheMaxAge().get();
4815 if ((max_age == 0) || (age > max_age)) {
4821 if (!subnet->getCacheThreshold().unspecified()) {
4822 double threshold = subnet->getCacheThreshold().get();
4823 if ((threshold <= 0.) || (threshold > 1.)) {
4826 max_age = lease->valid_lft_ * threshold;
4827 if (age > max_age) {
4839 (current_preferred_lft == 0)) {
4841 lease->reuseable_preferred_lft_ = current_preferred_lft;
4842 }
else if (current_preferred_lft > age) {
4843 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
4851 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
void clearReclaimedExtendedInfo(const Lease4Ptr &lease) const
Clear extended info from a reclaimed V4 lease.
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...
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_SELECT_SKIP
static HostMgr & instance()
Returns a sole instance of the HostMgr.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_COMPLETE
bool fake_allocation_
Indicates if this is a real or fake allocation.
boost::shared_ptr< DUID > DuidPtr
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_COMPLETE
const int ALLOC_ENGINE_DBG_TRACE
Logging levels for the AllocEngine.
static bool subnetsIncludeMatchClientId(const Subnet4Ptr &first_subnet, const ClientClasses &client_classes)
Checks if the shared network includes a subnet with the match client ID flag set to true...
static std::string makeLabel(const HWAddrPtr &hwaddr, const ClientIdPtr &client_id, const uint32_t transid)
Returns text representation of the given packet identifiers.
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Structure that holds a lease for IPv4 address.
Lease6Collection changed_leases_
A pointer to any leases that have changed FQDN information.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_IN_USE
HintContainer hints_
Client's hints.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
static void packOptions6(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options)
Stores DHCPv6 options in a buffer.
static void findReservation(ClientContext6 &ctx)
Attempts to find appropriate host reservation.
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
delete reference to the lease
isc::util::ReadWriteMutex rw_mutex_
The read-write mutex.
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_START
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_ERROR
virtual ConstHostCollection getAll6(const SubnetID &subnet_id) const
Return all hosts in a DHCPv6 subnet.
bool getDisableSingleQuery() const
Returns the disable single query flag.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_TIMEOUT
void addAllocatedResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding allocated prefix or address.
static IPv6Resrv makeIPv6Resrv(const Lease6 &lease)
Creates an IPv6Resrv instance from a Lease6.
Lease6Collection old_leases_
A pointer to any old leases that the client had before update but are no longer valid after the updat...
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_SLOW
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RENEW_SKIP
static ConstHostPtr findGlobalReservation(ClientContext6 &ctx)
Attempts to find the host reservation for the client.
static CfgMgr & instance()
returns a single instance of Configuration Manager
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL
Write mutex RAII handler.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAMATION_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_HR_ADDR_GRANTED
const int DHCPSRV_DBG_HOOKS
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_UNRESERVED
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_HR
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
virtual ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID ALLOC_ENGINE_V4_NO_MORE_EXPIRED_LEASES
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
static void getLifetimes6(ClientContext6 &ctx, uint32_t &preferred, uint32_t &valid)
Determines the preferred and valid v6 lease lifetimes.
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_HR
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
Resource race avoidance RAII handler for DHCPv4.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
the lease contains IPv6 prefix (for prefix delegation)
boost::shared_ptr< Element > ElementPtr
const int ALLOC_ENGINE_DBG_TRACE_DETAIL
Record detailed traces.
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv4 leases.
bool fwd_dns_update_
A boolean value which indicates that server takes responsibility for the forward DNS Update for this ...
DuidPtr duid_
Client identifier.
long getTotalMilliseconds() const
Retrieves the total measured duration in milliseconds.
Lease4Ptr allocateLease4(ClientContext4 &ctx)
Returns IPv4 lease.
bool isAllocated(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was allocated.
A configuration holder for IPv4 subnet.
Forward declaration to OptionInt.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_TIMEOUT
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED
IPv6 reservation for a host.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ERROR
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
const_iterator cbegin() const
Iterators to the first element.
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
RAII object enabling copying options retrieved from the packet.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SHARED_NETWORK
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_NEW_LEASE
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_RECOVER_SKIP
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv6 leases.
Statistics Manager class.
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
asiolink::IOAddress requested_address_
An address that the client desires.
Resource race avoidance RAII handler.
void deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
const isc::log::MessageID ALLOC_ENGINE_V6_HR_PREFIX_GRANTED
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
void addNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding new prefix or address.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SHARED_NETWORK
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
ResourceContainer new_resources_
Holds addresses and prefixes allocated for this IA.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAMATION_FAILED
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
void stop()
Stops the stopwatch.
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
PrefixLenMatchType
Type of preferred PD-pool prefix length selection criteria.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
ClientClassContainer::const_iterator const_iterator
Type of iterators.
Subnet6Ptr subnet_
Subnet selected for the client by the server.
ResourceContainer allocated_resources_
Holds addresses and prefixes allocated for all IAs.
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
Pool information for IPv6 addresses and prefixes.
const int ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA
Records detailed results of various operations.
Lease4Ptr conflicting_lease_
A pointer to the object representing a lease in conflict.
static std::string labelNetworkOrSubnet(SubnetPtr subnet)
Generates a label for subnet or shared-network from subnet.
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RECOVER_SKIP
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL
const isc::log::MessageID ALLOC_ENGINE_V6_HINT_RESERVED
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
Lease4Ptr old_lease_
A pointer to an old lease that the client had before update.
Utility class to measure code execution times.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE_DATA
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_PREFIX_LEASE
bool updateLease4ExtendedInfo(const Lease4Ptr &lease, const ClientContext4 &ctx) const
Stores additional client query parameters on a V4 lease.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL
std::vector< IAContext > ias_
Container holding IA specific contexts.
Context information for the DHCPv6 leases allocation.
const isc::log::MessageID ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
Subnet6Ptr host_subnet_
Subnet from which host reservations should be retrieved.
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.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
Notes: IntElement type is changed to int64_t.
Lease6Collection renewLeases6(ClientContext6 &ctx)
Renews existing DHCPv6 leases for a given IA.
Wrapper class around callout handle which automatically resets handle's state.
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.
Subnet4Ptr subnet_
Subnet selected for the client by the server.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
T get(T hint) const
Returns value with a hint.
bool unknown_requested_addr_
True when the address DHCPREQUEST'ed by client is not within a dynamic pool the server knows about...
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_FAILED
Pkt4Ptr query_
A pointer to the client's message.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAIM
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_START
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
Option6IAPtr ia_rsp_
A pointer to the IA_NA/IA_PD option to be sent in response.
CalloutNextStep
Specifies allowed next steps.
ClientContext4()
Default constructor.
boost::shared_ptr< const Element > ConstElementPtr
const void * getData() const
Return a pointer to the head of the data stored in the buffer.
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
Structure that holds a lease for IPv6 address and/or prefix.
update extended info tables.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_CLASSES
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.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_NO_POOLS
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_SLOW
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
const isc::log::MessageID ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
Type
Type of the reservation.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv4 leases.
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_FAILED
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
bool empty() const
Check if classes is empty.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
the lease contains non-temporary IPv6 address
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SUBNET
size_t getLength() const
Return the length of data written in the buffer.
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
ConstHostPtr currentHost() const
Returns host for currently selected subnet.
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_HR
bool fake_allocation_
Indicates if this is a real or fake allocation.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_CLASSES
This is a base class for exceptions thrown from the DNS library module.
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_FAILED
bool isNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was new.
static std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
Lease6Collection new_leases_
A collection of newly allocated leases.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 ('hex') format.
ClientIdPtr clientid_
Client identifier from the DHCP message.
uint32_t iaid_
The IAID field from IA_NA or IA_PD that is being processed.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_V6_HR
std::string toText() const
Convert the address to a string.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAIM
Lease::Type type_
Lease type (IA or PD)
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_COMPLETE
Pkt6Ptr query_
A pointer to the client's message.
virtual ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv4 subnet.
Lease6Collection allocateLeases6(ClientContext6 &ctx)
Allocates IPv6 leases for a given IA container.
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
virtual ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len) const
Returns a host connected to the IPv6 subnet.
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_NO_POOLS
Lease4Ptr new_lease_
A pointer to a newly allocated lease.
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_COMPLETE
static ElementPtr create(const Position &pos=ZERO_POSITION())
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA
a common structure for IPv4 and IPv6 leases
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED
Type
Type of lease or pool.
static TrackingLeaseMgr & instance()
Return current lease manager.
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_SELECT_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE
IAContext()
Default constructor.
bool rev_dns_update_
A boolean value which indicates that server takes responsibility for the reverse DNS Update for this ...
bool fwd_dns_update_
Perform forward DNS update.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SUBNET
isc::log::Logger alloc_engine_logger("alloc-engine")
Logger for the AllocEngine.
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_EXTEND_SKIP
virtual ConstHostCollection getAll4(const SubnetID &subnet_id) const
Return all hosts in a DHCPv4 subnet.
A generic exception that is thrown if a function is called in a prohibited way.
static uint32_t getValidLft(const ClientContext4 &ctx)
Returns the valid lifetime based on the v4 context.
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_ADDR_LEASE
const_iterator cend() const
Iterators to the past the end element.
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
void deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE
virtual bool addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
IAContext & currentIA()
Returns IA specific context for the currently processed IA.
static const uint32_t STATE_DEFAULT
A lease in the default state.
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.
const isc::log::MessageID ALLOC_ENGINE_V4_DECLINED_RECOVERED
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
std::string hostname_
Hostname.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
const isc::log::MessageID ALLOC_ENGINE_LEASE_RECLAIMED
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
static const uint32_t STATE_DECLINED
Declined lease.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_ERROR
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_PREFIX_LEASE
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS6
T getValue() const
Return option value.
bool hasGlobalReservation(const IPv6Resrv &resv) const
Determines if a global reservation exists.
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
std::pair< IPv6Resrv::Type, IPv6Resrv > IPv6ResrvTuple
HWAddrPtr hwaddr_
HW address from the DHCP message.
The IOAddress class represents an IP addresses (version agnostic)
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS
std::string hostname_
Hostname.
virtual Lease6Collection getLeases6(Lease::Type type, const DUID &duid, uint32_t iaid) const =0
Returns existing IPv6 leases for a given DUID+IA combination.
Context information for the DHCPv4 lease allocation.
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_ADDR_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_INVALID
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv6 leases.
std::string logFormatTotalDuration() const
Returns the total measured duration in the format directly usable in the log messages.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
ConstHostPtr currentHost() const
Returns host from the most preferred subnet.
std::pair< Host::IdentifierType, std::vector< uint8_t > > IdentifierPair
A tuple holding host identifier type and value.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED
Container for storing client class names.
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.
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS
bool rev_dns_update_
Perform reverse DNS update.
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_USE_HR
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
const isc::log::MessageID ALLOC_ENGINE_V6_NO_MORE_EXPIRED_LEASES
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR
void updateLease6ExtendedInfo(const Lease6Ptr &lease, const ClientContext6 &ctx) const
Stores additional client query parameters on a V6 lease.
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_ADDRESS_CONFLICT