33 #include <boost/foreach.hpp> 34 #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::IterativeAllocator::IterativeAllocator(
Lease::Type lease_type)
99 const uint8_t prefix_len) {
100 if (!prefix.
isV6()) {
102 "increase prefix " << prefix <<
")");
106 const std::vector<uint8_t>& vec = prefix.
toBytes();
108 if (prefix_len < 1 || prefix_len > 128) {
113 uint8_t n_bytes = (prefix_len - 1)/8;
114 uint8_t n_bits = 8 - (prefix_len - n_bytes*8);
115 uint8_t mask = 1 << n_bits;
124 uint8_t packed[V6ADDRESS_LEN];
127 std::memcpy(packed, &vec[0], V6ADDRESS_LEN);
130 if (packed[n_bytes] + uint16_t(mask) < 256u) {
131 packed[n_bytes] += mask;
136 packed[n_bytes] += mask;
139 for (
int i = n_bytes - 1; i >= 0; --i) {
142 if (packed[i] != 0) {
153 const uint8_t prefix_len) {
162 AllocEngine::IterativeAllocator::pickAddressInternal(
const SubnetPtr& subnet,
168 uint8_t prefix_len = 0;
175 bool retrying =
false;
184 PoolCollection::const_iterator it;
185 PoolCollection::const_iterator first = pools.end();
187 for (it = pools.begin(); it != pools.end(); ++it) {
188 if (!(*it)->clientSupported(client_classes)) {
191 if (first == pools.end()) {
194 if ((*it)->inRange(last)) {
200 if (first == pools.end()) {
209 if (it == pools.end()) {
216 for (; it != pools.end(); ++it) {
217 if ((*it)->clientSupported(client_classes)) {
221 if (it == pools.end()) {
227 last = (*it)->getLastAllocated();
228 valid = (*it)->isLastAllocatedValid();
229 if (!valid && (last == (*it)->getFirstAddress())) {
231 (*it)->setLastAllocated(last);
236 if (valid && !(*it)->inRange(last)) {
238 (*it)->resetLastAllocated();
239 (*it)->setLastAllocated((*it)->getFirstAddress());
254 prefix_len = pool6->getLength();
258 if ((*it)->inRange(next)) {
261 (*it)->setLastAllocated(next);
267 (*it)->resetLastAllocated();
275 for (it = first; it != pools.end(); ++it) {
276 if ((*it)->clientSupported(client_classes)) {
277 (*it)->setLastAllocated((*it)->getFirstAddress());
278 (*it)->resetLastAllocated();
283 last = (*first)->getLastAllocated();
284 (*first)->setLastAllocated(last);
295 AllocEngine::HashedAllocator::pickAddressInternal(
const SubnetPtr&,
308 AllocEngine::RandomAllocator::pickAddressInternal(
const SubnetPtr&,
317 : attempts_(attempts), incomplete_v4_reclamations_(0),
318 incomplete_v6_reclamations_(0) {
324 switch (engine_type) {
341 switch (engine_type) {
360 hook_index_lease4_select_ =
Hooks.hook_index_lease4_select_;
361 hook_index_lease6_select_ =
Hooks.hook_index_lease6_select_;
365 std::map<Lease::Type, AllocatorPtr>::const_iterator alloc = allocators_.find(type);
367 if (alloc == allocators_.end()) {
371 return (alloc->second);
398 if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
401 reserved.push_back(host);
405 reserved.insert(reserved.end(), hosts.begin(), hosts.end());
424 const IOAddress& address,
bool check_subnet) {
428 while (current_subnet) {
430 if (current_subnet->clientSupported(ctx.
query_->getClasses())) {
432 if (current_subnet->inPool(lease_type, address)) {
436 if (current_subnet->inPool(lease_type, address,
437 ctx.
query_->getClasses())) {
443 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
459 : query_(), fake_allocation_(false),
460 early_global_reservations_lookup_(false), subnet_(), host_subnet_(),
461 duid_(), hwaddr_(), host_identifiers_(), hosts_(),
462 fwd_dns_update_(false), rev_dns_update_(false), hostname_(),
463 callout_handle_(), ias_(), ddns_params_() {
470 const std::string& hostname,
471 const bool fake_allocation,
479 ias_(), ddns_params_() {
488 : iaid_(0), type_(
Lease::TYPE_NA), hints_(), old_leases_(),
489 changed_leases_(), new_resources_(), ia_rsp_() {
495 const uint8_t prefix_len,
496 const uint32_t preferred,
497 const uint32_t valid) {
507 addHint(iaaddr->getAddress(), 128,
508 iaaddr->getPreferred(), iaaddr->getValid());
517 addHint(iaprefix->getAddress(), iaprefix->getLength(),
518 iaprefix->getPreferred(), iaprefix->getValid());
524 const uint8_t prefix_len) {
531 const uint8_t prefix_len)
const {
539 const uint8_t prefix_len) {
547 return (static_cast<bool>
554 if (subnet && subnet->getReservationsInSubnet()) {
555 auto host =
hosts_.find(subnet->getID());
556 if (host !=
hosts_.cend()) {
557 return (host->second);
567 if (subnet &&
subnet_->getReservationsGlobal()) {
568 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
569 if (host !=
hosts_.cend()) {
570 return (host->second);
580 return (ghost && ghost->hasReservation(resv));
586 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
587 return (ddns_params_);
593 return (ddns_params_);
612 !subnet->getReservationsInSubnet()) {
618 subnet->getReservationsGlobal()) {
621 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
624 if (!subnet->getReservationsInSubnet()) {
630 std::map<SubnetID, ConstHostPtr> host_map;
632 subnet->getSharedNetwork(network);
641 const bool use_single_query = network &&
645 if (use_single_query) {
649 id_pair.second.size());
653 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
654 if ((*host)->getIPv6SubnetID() != SUBNET_ID_GLOBAL) {
655 host_map[(*host)->getIPv6SubnetID()] = *host;
666 if (subnet->clientSupported(ctx.
query_->getClasses()) &&
667 subnet->getReservationsInSubnet()) {
670 if (use_single_query) {
671 if (host_map.count(subnet->getID()) > 0) {
672 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
680 id_pair.second.size());
683 ctx.
hosts_[subnet->getID()] = host;
693 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
703 &id_pair.second[0], id_pair.second.size());
737 for (
auto l : all_leases) {
738 if ((l)->subnet_id_ == subnet->getID()) {
743 subnet = subnet->getNextSubnet(ctx.
subnet_);
763 if (leases.empty() && !ctx.
hosts_.empty()) {
767 .arg(ctx.
query_->getLabel());
772 allocateReservedLeases6(ctx, leases);
774 leases = updateLeaseData(ctx, leases);
789 }
else if (!leases.empty() && ctx.
hosts_.empty()) {
793 .arg(ctx.
query_->getLabel());
797 removeNonmatchingReservedLeases6(ctx, leases);
799 leases = updateLeaseData(ctx, leases);
808 }
else if (!leases.empty() && !ctx.
hosts_.empty()) {
812 .arg(ctx.
query_->getLabel());
816 allocateReservedLeases6(ctx, leases);
828 removeNonmatchingReservedLeases6(ctx, leases);
837 removeNonreservedLeases6(ctx, leases);
842 leases = updateLeaseData(ctx, leases);
855 if (leases.empty()) {
869 .arg(ctx.
query_->getLabel());
871 leases = allocateUnreservedLeases6(ctx);
874 if (!leases.empty()) {
889 .arg(ctx.
query_->getLabel())
921 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
923 if (!subnet->clientSupported(ctx.
query_->getClasses())) {
931 pool = boost::dynamic_pointer_cast<
Pool6>
936 if (!pool || !pool->clientSupported(ctx.
query_->getClasses())) {
940 bool in_subnet = subnet->getReservationsInSubnet();
957 (!subnet->getReservationsOutOfPool() ||
959 hosts = getIPv6Resrv(subnet->getID(), hint);
968 lease = createLease6(ctx, hint, pool->getLength(), callout_status);
978 collection.push_back(lease);
984 .arg(ctx.
query_->getLabel())
988 }
else if (lease->expired()) {
997 (!subnet->getReservationsOutOfPool() ||
999 hosts = getIPv6Resrv(subnet->getID(), hint);
1003 if (hosts.empty()) {
1011 lease = reuseExpiredLease(lease, ctx, pool->getLength(),
1015 leases.push_back(lease);
1021 .arg(ctx.
query_->getLabel())
1030 bool check_reservation_first = MultiThreadingMgr::instance().getMode();
1033 if (!check_reservation_first) {
1037 uint64_t total_attempts = 0;
1049 original_subnet->getSharedNetwork(network);
1056 original_subnet = network->getPreferredSubnet(original_subnet, ctx.
currentIA().
type_);
1059 ctx.
subnet_ = subnet = original_subnet;
1063 uint64_t subnets_with_unavail_leases = 0;
1066 uint64_t subnets_with_unavail_pools = 0;
1068 for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
1070 if (!subnet->clientSupported(ctx.
query_->getClasses())) {
1080 uint64_t possible_attempts =
1082 ctx.
query_->getClasses());
1089 uint64_t max_attempts = ((attempts_ == 0) || (possible_attempts < attempts_)) ? possible_attempts : attempts_;
1091 if (max_attempts > 0) {
1094 ++subnets_with_unavail_leases;
1098 ++subnets_with_unavail_pools;
1102 bool in_subnet = subnet->getReservationsInSubnet();
1103 bool out_of_pool = subnet->getReservationsOutOfPool();
1112 for (uint64_t i = 0; i < max_attempts; ++i) {
1116 IOAddress candidate = allocator->pickAddress(subnet,
1117 ctx.
query_->getClasses(),
1122 uint8_t prefix_len = 128;
1124 pool = boost::dynamic_pointer_cast<
Pool6>(
1126 ctx.
query_->getClasses(),
1129 prefix_len = pool->getLength();
1134 if (check_reservation_first && in_subnet && !out_of_pool) {
1135 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1136 if (!hosts.empty()) {
1145 if (MultiThreadingMgr::instance().getMode() &&
1159 if (!check_reservation_first && in_subnet && !out_of_pool) {
1160 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1161 if (!hosts.empty()) {
1171 Lease6Ptr lease = createLease6(ctx, candidate, prefix_len, callout_status);
1177 leases.push_back(lease);
1181 (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
1189 }
else if (existing->expired()) {
1191 if (!check_reservation_first && in_subnet && !out_of_pool) {
1192 auto hosts = getIPv6Resrv(subnet->getID(), candidate);
1193 if (!hosts.empty()) {
1205 existing = reuseExpiredLease(existing, ctx, prefix_len,
1208 leases.push_back(existing);
1218 .arg(ctx.
query_->getLabel())
1219 .arg(network->getName())
1220 .arg(subnets_with_unavail_leases)
1221 .arg(subnets_with_unavail_pools);
1222 StatsMgr::instance().addValue(
"v6-allocation-fail-shared-network",
1223 static_cast<int64_t>(1));
1224 StatsMgr::instance().addValue(
1225 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1226 "v6-allocation-fail-shared-network"),
1227 static_cast<int64_t>(1));
1232 .arg(ctx.
query_->getLabel())
1234 StatsMgr::instance().addValue(
"v6-allocation-fail-subnet",
1235 static_cast<int64_t>(1));
1236 StatsMgr::instance().addValue(
1237 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1238 "v6-allocation-fail-subnet"),
1239 static_cast<int64_t>(1));
1241 if (total_attempts == 0) {
1247 .arg(ctx.
query_->getLabel());
1248 StatsMgr::instance().addValue(
"v6-allocation-fail-no-pools",
1249 static_cast<int64_t>(1));
1250 StatsMgr::instance().addValue(
1251 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1252 "v6-allocation-fail-no-pools"),
1253 static_cast<int64_t>(1));
1260 .arg(ctx.
query_->getLabel())
1261 .arg(total_attempts);
1262 StatsMgr::instance().addValue(
"v6-allocation-fail",
1263 static_cast<int64_t>(1));
1264 StatsMgr::instance().addValue(
1265 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1266 "v6-allocation-fail"),
1267 static_cast<int64_t>(1));
1271 if (!classes.
empty()) {
1273 .arg(ctx.
query_->getLabel())
1275 StatsMgr::instance().addValue(
"v6-allocation-fail-classes",
1276 static_cast<int64_t>(1));
1277 StatsMgr::instance().addValue(
1278 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1279 "v6-allocation-fail-classes"),
1280 static_cast<int64_t>(1));
1292 if (ctx.
hosts_.empty()) {
1295 .arg(ctx.
query_->getLabel());
1306 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1307 if ((lease->valid_lft_ != 0)) {
1308 if ((ctx.
hosts_.count(lease->subnet_id_) > 0) &&
1314 .arg(ctx.
query_->getLabel())
1315 .arg(lease->typeToText(lease->type_))
1316 .arg(lease->addr_.toText());
1324 ctx.
subnet_->getSharedNetwork(network);
1329 ctx.
host_subnet_ = network->getSubnet(lease->subnet_id_);
1337 if (host && !host->getHostname().empty()) {
1345 static_cast<bool>(fqdn));
1360 subnet = subnet->getNextSubnet(ctx.
subnet_)) {
1362 SubnetID subnet_id = subnet->getID();
1365 if (!subnet->clientSupported(ctx.
query_->getClasses()) ||
1366 ctx.
hosts_.count(subnet_id) == 0) {
1372 bool in_subnet = subnet->getReservationsInSubnet();
1378 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1379 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1392 (subnet->getReservationsOutOfPool() &&
1409 if (!host->getHostname().empty()) {
1424 static_cast<bool>(fqdn));
1430 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1433 existing_leases.push_back(lease);
1438 .arg(ctx.
query_->getLabel());
1442 .arg(static_cast<int>(prefix_len))
1443 .arg(ctx.
query_->getLabel());
1461 allocateGlobalReservedLeases6(ctx, existing_leases);
1476 BOOST_FOREACH(
const Lease6Ptr& lease, existing_leases) {
1477 if ((lease->valid_lft_ != 0) &&
1483 .arg(ctx.
query_->getLabel())
1484 .arg(lease->typeToText(lease->type_))
1485 .arg(lease->addr_.toText());
1491 if (!ghost->getHostname().empty()) {
1499 static_cast<bool>(fqdn));
1514 const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
1517 const IOAddress& addr = type_lease_tuple.second.getPrefix();
1518 uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
1530 if (!ghost->getHostname().empty()) {
1545 static_cast<bool>(fqdn));
1550 Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
1553 existing_leases.push_back(lease);
1558 .arg(ctx.
query_->getLabel());
1562 .arg(static_cast<int>(prefix_len))
1563 .arg(ctx.
query_->getLabel());
1581 AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
1584 if (existing_leases.empty() || !ctx.
subnet_) {
1589 if (!ctx.
subnet_->getReservationsInSubnet() &&
1590 !ctx.
subnet_->getReservationsGlobal()) {
1591 removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
1600 BOOST_FOREACH(
const Lease6Ptr& candidate, copy) {
1605 ((ctx.
hosts_.count(candidate->subnet_id_) > 0) &&
1606 (ctx.
hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
1615 auto hosts = getIPv6Resrv(ctx.
subnet_->getID(), candidate->addr_);
1620 if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
1621 candidate->addr_,
false)) {
1625 if (!hosts.empty()) {
1628 if (hosts.size() == 1) {
1631 .arg(candidate->addr_.toText())
1632 .arg(ctx.
duid_->toText())
1633 .arg(hosts.front()->getIdentifierAsText());
1636 .arg(candidate->addr_.toText())
1637 .arg(static_cast<int>(candidate->prefixlen_))
1638 .arg(ctx.
duid_->toText())
1639 .arg(hosts.front()->getIdentifierAsText());
1644 .arg(candidate->addr_.toText())
1645 .arg(ctx.
duid_->toText())
1649 .arg(candidate->addr_.toText())
1650 .arg(static_cast<int>(candidate->prefixlen_))
1651 .arg(ctx.
duid_->toText())
1669 StatsMgr::instance().addValue(
1670 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1672 "assigned-nas" :
"assigned-pds"),
1673 static_cast<int64_t>(-1));
1684 removeLeases(existing_leases, candidate->addr_);
1689 AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
1696 BOOST_FOREACH(
const Lease6Ptr& candidate, copy) {
1700 if (inAllowedPool(ctx, candidate->type_,
1701 candidate->addr_,
false)) {
1716 StatsMgr::instance().addValue(
1717 StatsMgr::generateName(
"subnet", candidate->subnet_id_,
1719 "assigned-nas" :
"assigned-pds"),
1720 static_cast<int64_t>(-1));
1726 removeLeases(existing_leases, candidate->addr_);
1733 bool removed =
false;
1734 for (Lease6Collection::iterator lease = container.begin();
1735 lease != container.end(); ++lease) {
1736 if ((*lease)->addr_ == addr) {
1743 container.erase(std::remove(container.begin(), container.end(),
Lease6Ptr()),
1754 int total = existing_leases.size();
1761 for (Lease6Collection::iterator lease = existing_leases.begin();
1762 lease != existing_leases.end(); ++lease) {
1767 ((ctx.
hosts_.count((*lease)->subnet_id_) > 0) &&
1768 (ctx.
hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
1787 StatsMgr::instance().addValue(
1788 StatsMgr::generateName(
"subnet", (*lease)->subnet_id_,
1790 "assigned-nas" :
"assigned-pds"),
1791 static_cast<int64_t>(-1));
1812 existing_leases.erase(std::remove(existing_leases.begin(),
1813 existing_leases.end(),
Lease6Ptr()), existing_leases.end());
1821 if (!expired->expired()) {
1838 expired->duid_ = ctx.
duid_;
1844 expired->preferred_lft_ = ctx.
subnet_->getPreferred().get(preferred);
1846 expired->preferred_lft_ = ctx.
subnet_->getPreferred();
1850 expired->reuseable_valid_lft_ = 0;
1854 expired->valid_lft_ = ctx.
subnet_->getValid().get(valid);
1856 expired->valid_lft_ = ctx.
subnet_->getValid();
1858 expired->cltt_ = time(NULL);
1859 expired->subnet_id_ = ctx.
subnet_->getID();
1863 expired->prefixlen_ = prefix_len;
1868 .arg(ctx.
query_->getLabel())
1869 .arg(expired->toText());
1873 HooksManager::calloutsPresent(hook_index_lease6_select_)) {
1899 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.
callout_handle_);
1906 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
1931 StatsMgr::instance().addValue(
1932 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1934 "assigned-nas" :
"assigned-pds"),
1935 static_cast<int64_t>(1));
1936 StatsMgr::instance().addValue(
1937 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
1939 "cumulative-assigned-nas" :
1940 "cumulative-assigned-pds"),
1941 static_cast<int64_t>(1));
1943 "cumulative-assigned-nas" :
1944 "cumulative-assigned-pds",
1945 static_cast<int64_t
>(1));
1964 if (!classes.
empty()) {
1971 for (
auto name = classes.
cbegin();
1972 name != classes.
cend() && have_both < 2; ++name) {
1975 (cl && (!cl->getPreferred().unspecified()))) {
1976 candidate_preferred = cl->getPreferred();
1981 (cl && (!cl->getValid().unspecified()))) {
1982 candidate_valid = cl->getValid();
1989 if (!candidate_preferred) {
1990 candidate_preferred = ctx.
subnet_->getPreferred();
1994 if (!candidate_valid) {
1995 candidate_valid = ctx.
subnet_->getValid();
1999 preferred = candidate_preferred;
2000 valid = candidate_valid;
2024 uint32_t preferred = 0;
2039 HooksManager::calloutsPresent(hook_index_lease6_select_)) {
2065 HooksManager::callCallouts(hook_index_lease6_select_, *ctx.
callout_handle_);
2072 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
2093 StatsMgr::instance().addValue(
2094 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2096 "assigned-nas" :
"assigned-pds"),
2097 static_cast<int64_t>(1));
2098 StatsMgr::instance().addValue(
2099 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2101 "cumulative-assigned-nas" :
2102 "cumulative-assigned-pds"),
2103 static_cast<int64_t>(1));
2105 "cumulative-assigned-nas" :
2106 "cumulative-assigned-pds",
2107 static_cast<int64_t
>(1));
2150 leases.insert(leases.end(), leases_subnet.begin(), leases_subnet.end());
2152 subnet = subnet->getNextSubnet(ctx.
subnet_);
2155 if (!leases.empty()) {
2158 .arg(ctx.
query_->getLabel());
2162 removeNonmatchingReservedLeases6(ctx, leases);
2165 if (!ctx.
hosts_.empty()) {
2169 .arg(ctx.
query_->getLabel());
2172 allocateReservedLeases6(ctx, leases);
2178 removeNonreservedLeases6(ctx, leases);
2185 if (leases.empty()) {
2189 .arg(ctx.
query_->getLabel());
2191 leases = allocateUnreservedLeases6(ctx);
2195 for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
2197 (*l)->prefixlen_)) {
2203 .arg(ctx.
query_->getLabel())
2204 .arg((*l)->typeToText((*l)->type_))
2206 extendLease6(ctx, *l);
2209 if (!leases.empty()) {
2213 BOOST_FOREACH(
Lease6Ptr lease, leases) {
2225 .arg(ctx.
query_->getLabel())
2241 if (ctx.
subnet_->getID() != lease->subnet_id_) {
2243 ctx.
subnet_->getSharedNetwork(network);
2272 StatsMgr::instance().addValue(
2273 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
"assigned-nas"),
2274 static_cast<int64_t>(-1));
2284 .arg(ctx.
query_->getLabel())
2285 .arg(lease->toText());
2290 bool changed =
false;
2291 uint32_t current_preferred_lft = lease->preferred_lft_;
2295 lease->preferred_lft_ = ctx.
subnet_->getPreferred().get(preferred);
2297 lease->preferred_lft_ = ctx.
subnet_->getPreferred();
2299 if (lease->preferred_lft_ < current_preferred_lft) {
2302 lease->reuseable_valid_lft_ = 0;
2306 lease->valid_lft_ = ctx.
subnet_->getValid().get(valid);
2308 lease->valid_lft_ = ctx.
subnet_->getValid();
2310 if (lease->valid_lft_ < lease->current_valid_lft_) {
2314 lease->cltt_ = time(NULL);
2323 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
2325 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
2335 .arg(ctx.
query_->getLabel())
2336 .arg(lease->toText());
2341 Hooks.hook_index_lease6_renew_ :
Hooks.hook_index_lease6_rebind_;
2342 if (HooksManager::calloutsPresent(hook_point)) {
2355 callout_handle->setArgument(
"query6", ctx.
query_);
2358 callout_handle->setArgument(
"lease6", lease);
2368 HooksManager::callCallouts(hook_point, *callout_handle);
2373 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
2377 .arg(ctx.
query_->getName());
2384 bool update_stats =
false;
2388 if (old_data->expired()) {
2394 update_stats =
true;
2406 setLeaseReusable(lease, current_preferred_lft, ctx);
2412 if (lease->reuseable_valid_lft_ == 0) {
2417 StatsMgr::instance().addValue(
2418 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2420 "assigned-nas" :
"assigned-pds"),
2421 static_cast<int64_t>(1));
2422 StatsMgr::instance().addValue(
2423 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
2425 "cumulative-assigned-nas" :
2426 "cumulative-assigned-pds"),
2427 static_cast<int64_t>(1));
2429 "cumulative-assigned-nas" :
2430 "cumulative-assigned-pds",
2431 static_cast<int64_t
>(1));
2450 for (Lease6Collection::const_iterator lease_it = leases.begin();
2451 lease_it != leases.end(); ++lease_it) {
2455 updated_leases.push_back(lease);
2459 lease->reuseable_valid_lft_ = 0;
2464 bool update_stats =
false;
2473 lease->addr_,
true)) {
2474 update_stats =
true;
2479 !(lease->hasIdenticalFqdn(**lease_it)));
2481 lease->cltt_ = time(NULL);
2482 if (!fqdn_changed) {
2483 uint32_t current_preferred_lft = lease->preferred_lft_;
2484 setLeaseReusable(lease, current_preferred_lft, ctx);
2486 if (lease->reuseable_valid_lft_ == 0) {
2492 StatsMgr::instance().addValue(
2493 StatsMgr::generateName(
"subnet", lease->subnet_id_,
2495 "assigned-nas" :
"assigned-pds"),
2496 static_cast<int64_t>(1));
2497 StatsMgr::instance().addValue(
2498 StatsMgr::generateName(
"subnet", lease->subnet_id_,
2500 "cumulative-assigned-nas" :
2501 "cumulative-assigned-pds"),
2502 static_cast<int64_t>(1));
2504 "cumulative-assigned-nas" :
2505 "cumulative-assigned-pds",
2506 static_cast<int64_t
>(1));
2510 updated_leases.push_back(lease);
2513 return (updated_leases);
2518 const bool remove_lease,
2519 const uint16_t max_unwarned_cycles) {
2534 bool incomplete_reclamation =
false;
2537 if (max_leases > 0) {
2546 if (leases.size() > max_leases) {
2548 incomplete_reclamation =
true;
2561 if (!leases.empty() &&
2562 HooksManager::calloutsPresent(
Hooks.hook_index_lease6_expire_)) {
2563 callout_handle = HooksManager::createCalloutHandle();
2566 size_t leases_processed = 0;
2567 BOOST_FOREACH(
Lease6Ptr lease, leases) {
2571 if (MultiThreadingMgr::instance().getMode()) {
2575 reclaimExpiredLease(lease, remove_lease, callout_handle);
2578 reclaimExpiredLease(lease, remove_lease, callout_handle);
2582 }
catch (
const std::exception& ex) {
2584 .arg(lease->addr_.toText())
2595 if (!incomplete_reclamation) {
2596 if (leases_processed < leases.size()) {
2597 incomplete_reclamation =
true;
2614 .arg(leases_processed)
2619 if (incomplete_reclamation) {
2620 ++incomplete_v6_reclamations_;
2623 if ((max_unwarned_cycles > 0) &&
2624 (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
2626 .arg(max_unwarned_cycles);
2628 incomplete_v6_reclamations_ = 0;
2633 incomplete_v6_reclamations_ = 0;
2646 uint64_t deleted_leases = 0;
2652 }
catch (
const std::exception& ex) {
2659 .arg(deleted_leases);
2664 const bool remove_lease,
2665 const uint16_t max_unwarned_cycles) {
2680 bool incomplete_reclamation =
false;
2683 if (max_leases > 0) {
2692 if (leases.size() > max_leases) {
2694 incomplete_reclamation =
true;
2707 if (!leases.empty() &&
2708 HooksManager::calloutsPresent(
Hooks.hook_index_lease4_expire_)) {
2709 callout_handle = HooksManager::createCalloutHandle();
2712 size_t leases_processed = 0;
2713 BOOST_FOREACH(
Lease4Ptr lease, leases) {
2717 if (MultiThreadingMgr::instance().getMode()) {
2721 reclaimExpiredLease(lease, remove_lease, callout_handle);
2724 reclaimExpiredLease(lease, remove_lease, callout_handle);
2728 }
catch (
const std::exception& ex) {
2730 .arg(lease->addr_.toText())
2741 if (!incomplete_reclamation) {
2742 if (leases_processed < leases.size()) {
2743 incomplete_reclamation =
true;
2760 .arg(leases_processed)
2765 if (incomplete_reclamation) {
2766 ++incomplete_v4_reclamations_;
2769 if ((max_unwarned_cycles > 0) &&
2770 (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
2772 .arg(max_unwarned_cycles);
2774 incomplete_v4_reclamations_ = 0;
2779 incomplete_v4_reclamations_ = 0;
2786 template<
typename LeasePtrType>
2788 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
const bool remove_lease,
2790 reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
2794 template<
typename LeasePtrType>
2796 AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
2801 if (!lease->stateExpiredReclaimed()) {
2802 reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
2807 AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
2808 const DbReclaimMode& reclaim_mode,
2814 .arg(lease->addr_.toText())
2815 .arg(static_cast<int>(lease->prefixlen_));
2821 bool skipped =
false;
2822 if (callout_handle) {
2830 callout_handle->deleteAllArguments();
2831 callout_handle->setArgument(
"lease6", lease);
2832 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2834 HooksManager::callCallouts(
Hooks.hook_index_lease6_expire_,
2837 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2852 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2862 remove_lease = reclaimDeclined(lease);
2865 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2869 reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
2871 &lease_mgr, ph::_1));
2880 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2887 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2895 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2898 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2900 "reclaimed-leases"),
2905 AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
2906 const DbReclaimMode& reclaim_mode,
2912 .arg(lease->addr_.toText());
2918 bool skipped =
false;
2919 if (callout_handle) {
2927 callout_handle->setArgument(
"lease4", lease);
2928 callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
2930 HooksManager::callCallouts(
Hooks.hook_index_lease4_expire_,
2933 skipped = callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP;
2946 lease->hostname_.clear();
2947 lease->fqdn_fwd_ =
false;
2948 lease->fqdn_rev_ =
false;
2952 bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
2962 remove_lease = reclaimDeclined(lease);
2965 if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
2969 reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
2971 &lease_mgr, ph::_1));
2978 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2980 "assigned-addresses"),
2984 StatsMgr::instance().addValue(
"reclaimed-leases", int64_t(1));
2987 StatsMgr::instance().addValue(StatsMgr::generateName(
"subnet",
2989 "reclaimed-leases"),
2999 uint64_t deleted_leases = 0;
3005 }
catch (
const std::exception& ex) {
3012 .arg(deleted_leases);
3016 AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
3021 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_recover_)) {
3031 callout_handle->setArgument(
"lease4", lease);
3034 HooksManager::callCallouts(
Hooks.hook_index_lease4_recover_, *callout_handle);
3039 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3041 .arg(lease->addr_.toText());
3047 .arg(lease->addr_.toText())
3048 .arg(lease->valid_lft_);
3050 StatsMgr& stats_mgr = StatsMgr::instance();
3053 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
3054 "declined-addresses"), static_cast<int64_t>(-1));
3057 stats_mgr.
addValue(
"declined-addresses", static_cast<int64_t>(-1));
3059 stats_mgr.
addValue(
"reclaimed-declined-addresses", static_cast<int64_t>(1));
3061 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
3062 "reclaimed-declined-addresses"), static_cast<int64_t>(1));
3070 AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
3075 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease6_recover_)) {
3085 callout_handle->setArgument(
"lease6", lease);
3088 HooksManager::callCallouts(
Hooks.hook_index_lease6_recover_, *callout_handle);
3093 if (callout_handle->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
3095 .arg(lease->addr_.toText());
3101 .arg(lease->addr_.toText())
3102 .arg(lease->valid_lft_);
3104 StatsMgr& stats_mgr = StatsMgr::instance();
3107 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
3108 "declined-addresses"), static_cast<int64_t>(-1));
3111 stats_mgr.
addValue(
"declined-addresses", static_cast<int64_t>(-1));
3113 stats_mgr.
addValue(
"reclaimed-declined-addresses", static_cast<int64_t>(1));
3115 stats_mgr.
addValue(StatsMgr::generateName(
"subnet", lease->subnet_id_,
3116 "reclaimed-declined-addresses"), static_cast<int64_t>(1));
3124 template<
typename LeasePtrType>
3125 void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
3126 const bool remove_lease,
3127 const std::function<
void (
const LeasePtrType&)>&
3128 lease_update_fun)
const {
3136 }
else if (lease_update_fun) {
3139 lease->reuseable_valid_lft_ = 0;
3140 lease->hostname_.clear();
3141 lease->fqdn_fwd_ =
false;
3142 lease->fqdn_rev_ =
false;
3144 lease_update_fun(lease);
3153 .arg(lease->addr_.toText());
3189 (!ctx.
subnet_->getReservationsOutOfPool() ||
3204 hosts.push_back(host);
3211 for (
auto host : hosts) {
3215 if (id_pair.first == host->getIdentifierType() &&
3216 id_pair.second == host->getIdentifier()) {
3224 return (!hosts.empty());
3246 if (ctx.
hosts_.empty()) {
3251 bool search_global_done =
false;
3256 if (!search_global_done && subnet->getReservationsGlobal()) {
3257 auto host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
3260 if (host != ctx.
hosts_.end() && host->second &&
3261 !host->second->getIPv4Reservation().isV4Zero()) {
3266 search_global_done =
true;
3269 if (subnet->getReservationsInSubnet()) {
3270 auto host = ctx.
hosts_.find(subnet->getID());
3275 if (host != ctx.
hosts_.end() && host->second) {
3276 auto reservation = host->second->getIPv4Reservation();
3277 if (!reservation.isV4Zero() &&
3278 (!subnet->getReservationsOutOfPool() ||
3288 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3316 bool try_clientid_lookup = (ctx.
clientid_ &&
3318 ctx.
query_->getClasses()));
3321 if (try_clientid_lookup) {
3329 for (
Subnet4Ptr subnet = original_subnet; subnet;
3330 subnet = subnet->getNextSubnet(original_subnet,
3331 ctx.
query_->getClasses())) {
3336 if (subnet->getMatchClientId()) {
3337 for (
auto l = leases_client_id.begin(); l != leases_client_id.end(); ++l) {
3338 if ((*l)->subnet_id_ == subnet->getID()) {
3340 client_lease = (*l);
3351 if (!client_lease && ctx.
hwaddr_) {
3356 for (
Subnet4Ptr subnet = original_subnet; subnet;
3357 subnet = subnet->getNextSubnet(original_subnet,
3358 ctx.
query_->getClasses())) {
3360 if (subnet->getMatchClientId()) {
3366 for (Lease4Collection::const_iterator client_lease_it = leases_hw_address.begin();
3367 client_lease_it != leases_hw_address.end(); ++client_lease_it) {
3368 Lease4Ptr existing_lease = *client_lease_it;
3369 if ((existing_lease->subnet_id_ == subnet->getID()) &&
3370 existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
3372 client_lease = existing_lease;
3400 while (current_subnet) {
3403 ctx.
query_->getClasses())) {
3411 current_subnet = current_subnet->getNextSubnet(ctx.
subnet_,
3412 ctx.
query_->getClasses());
3426 requested_address_(
IOAddress::IPV4_ZERO_ADDRESS()),
3429 old_lease_(), new_lease_(),
hosts_(), conflicting_lease_(),
3438 const bool fwd_dns_update,
3439 const bool rev_dns_update,
3440 const std::string& hostname,
3441 const bool fake_allocation)
3461 if (host !=
hosts_.cend()) {
3462 return (host->second);
3472 auto host =
hosts_.find(SUBNET_ID_GLOBAL);
3473 if (host !=
hosts_.cend()) {
3474 return (host->second);
3484 if (ddns_params_ &&
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
3485 return (ddns_params_);
3491 return (ddns_params_);
3513 if (subnet && !subnet->clientSupported(ctx.
query_->getClasses())) {
3514 ctx.
subnet_ = subnet->getNextSubnet(subnet, ctx.
query_->getClasses());
3527 return (discoverLease4(ctx));
3536 .arg(ctx.
query_->getLabel())
3554 !subnet->getReservationsInSubnet()) {
3560 subnet->getReservationsGlobal()) {
3563 ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
3566 if (!subnet->getReservationsInSubnet()) {
3572 std::map<SubnetID, ConstHostPtr> host_map;
3574 subnet->getSharedNetwork(network);
3583 const bool use_single_query = network &&
3587 if (use_single_query) {
3591 id_pair.second.size());
3595 for (
auto host = hosts.begin(); host != hosts.end(); ++host) {
3596 if ((*host)->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
3597 host_map[(*host)->getIPv4SubnetID()] = *host;
3608 if (subnet->clientSupported(ctx.
query_->getClasses()) &&
3609 subnet->getReservationsInSubnet()) {
3612 if (use_single_query) {
3613 if (host_map.count(subnet->getID()) > 0) {
3614 ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
3622 id_pair.second.size());
3625 ctx.
hosts_[subnet->getID()] = host;
3635 subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
3645 &id_pair.second[0], id_pair.second.size());
3662 findClientLease(ctx, client_lease);
3672 if (hasAddressReservation(ctx)) {
3676 .arg(ctx.
query_->getLabel())
3677 .arg(ctx.
currentHost()->getIPv4Reservation().toText());
3683 if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
3690 new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
3694 .arg(ctx.
query_->getLabel())
3695 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3701 new_lease = renewLease4(client_lease, ctx);
3714 if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
3715 !addressReserved(client_lease->addr_, ctx)) {
3719 .arg(ctx.
query_->getLabel());
3721 new_lease = renewLease4(client_lease, ctx);
3738 .arg(ctx.
query_->getLabel());
3751 .arg(ctx.
query_->getLabel());
3753 new_lease = allocateUnreservedLease4(ctx);
3773 findClientLease(ctx, client_lease);
3789 .arg(ctx.
query_->getLabel())
3795 }
else if (hasAddressReservation(ctx)) {
3804 .arg(ctx.
query_->getLabel())
3816 if (existing && !existing->expired() &&
3817 !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
3822 .arg(ctx.
query_->getLabel())
3832 if (hasAddressReservation(ctx) &&
3840 if (!existing || existing->expired()) {
3844 .arg(ctx.
query_->getLabel())
3845 .arg(ctx.
currentHost()->getIPv4Reservation().toText())
3855 if ((!hasAddressReservation(ctx) ||
3861 .arg(ctx.
query_->getLabel())
3881 ((hasAddressReservation(ctx) &&
3883 inAllowedPool(ctx, client_lease->addr_))) {
3887 .arg(ctx.
query_->getLabel())
3890 return (renewLease4(client_lease, ctx));
3904 .arg(ctx.
query_->getLabel())
3920 .arg(ctx.
query_->getLabel());
3925 new_lease = allocateUnreservedLease4(ctx);
3931 if (new_lease && client_lease) {
3936 .arg(ctx.
query_->getLabel())
3937 .arg(client_lease->addr_.toText());
3941 StatsMgr::instance().addValue(
3942 StatsMgr::generateName(
"subnet", client_lease->subnet_id_,
3943 "assigned-addresses"),
3944 static_cast<int64_t>(-1));
3957 if (ctx.
query_->inClass(
"BOOTP")) {
3962 uint32_t requested_lft = 0;
3967 requested_lft = opt_lft->
getValue();
3975 if (!classes.
empty()) {
3982 name != classes.
cend(); ++name) {
3984 if (cl && (!cl->getValid().unspecified())) {
3985 candidate_lft = cl->getValid();
3992 if (!candidate_lft) {
3993 candidate_lft = ctx.
subnet_->getValid();
3998 if (requested_lft > 0) {
3999 return (candidate_lft.
get(requested_lft));
4003 return (candidate_lft.
get());
4019 time_t now = time(NULL);
4022 if (ctx.
subnet_->getMatchClientId()) {
4027 valid_lft, now, ctx.
subnet_->getID()));
4039 HooksManager::calloutsPresent(hook_index_lease4_select_)) {
4068 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.
callout_handle_);
4075 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
4091 StatsMgr::instance().addValue(
4092 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4093 "assigned-addresses"),
4094 static_cast<int64_t>(1));
4095 StatsMgr::instance().addValue(
4096 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4097 "cumulative-assigned-addresses"),
4098 static_cast<int64_t>(1));
4099 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4100 static_cast<int64_t>(1));
4120 AllocEngine::renewLease4(
const Lease4Ptr& lease,
4130 Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
4135 lease->reuseable_valid_lft_ = 0;
4136 if (!updateLease4Information(lease, ctx)) {
4137 setLeaseReusable(lease, ctx);
4153 if (HooksManager::calloutsPresent(
Hooks.hook_index_lease4_renew_)) {
4177 ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
4185 HooksManager::callCallouts(
Hooks.hook_index_lease4_renew_,
4191 if (ctx.
callout_handle_->getStatus() == CalloutHandle::NEXT_STEP_SKIP) {
4200 if (!ctx.
fake_allocation_ && !skip && (lease->reuseable_valid_lft_ == 0)) {
4206 StatsMgr::instance().addValue(
4207 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4208 "assigned-addresses"),
4209 static_cast<int64_t>(1));
4210 StatsMgr::instance().addValue(
4211 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4212 "cumulative-assigned-addresses"),
4213 static_cast<int64_t>(1));
4214 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4215 static_cast<int64_t>(1));
4221 *lease = *old_values;
4228 AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
4247 expired->reuseable_valid_lft_ = 0;
4248 static_cast<void>(updateLease4Information(expired, ctx));
4252 .arg(ctx.
query_->getLabel())
4253 .arg(expired->toText());
4257 HooksManager::calloutsPresent(hook_index_lease4_select_)) {
4286 HooksManager::callCallouts(hook_index_lease4_select_, *ctx.
callout_handle_);
4293 if (callout_status == CalloutHandle::NEXT_STEP_SKIP) {
4311 StatsMgr::instance().addValue(
4312 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4313 "assigned-addresses"),
4314 static_cast<int64_t>(1));
4315 StatsMgr::instance().addValue(
4316 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4317 "cumulative-assigned-addresses"),
4318 static_cast<int64_t>(1));
4319 StatsMgr::instance().addValue(
"cumulative-assigned-addresses",
4320 static_cast<int64_t>(1));
4338 if (exist_lease->expired()) {
4346 return (reuseExpiredLease4(exist_lease, ctx, callout_status));
4356 return (createLease4(ctx, candidate, callout_status));
4377 ctx.
subnet_->getSharedNetwork(network);
4390 bool check_reservation_first = MultiThreadingMgr::instance().getMode();
4394 uint64_t total_attempts = 0;
4398 uint64_t subnets_with_unavail_leases = 0;
4401 uint64_t subnets_with_unavail_pools = 0;
4405 if (subnet->getMatchClientId()) {
4409 uint64_t possible_attempts =
4411 ctx.
query_->getClasses());
4418 uint64_t max_attempts = ((attempts_ == 0 || possible_attempts < attempts_) ? possible_attempts : attempts_);
4420 if (max_attempts > 0) {
4423 ++subnets_with_unavail_leases;
4427 ++subnets_with_unavail_pools;
4432 for (uint64_t i = 0; i < max_attempts; ++i) {
4436 IOAddress candidate = allocator->pickAddress(subnet,
4437 ctx.
query_->getClasses(),
4441 if (check_reservation_first && addressReserved(candidate, ctx)) {
4449 if (MultiThreadingMgr::instance().getMode() &&
4450 !resource_handler.
tryLock4(candidate)) {
4459 if (check_reservation_first || !addressReserved(candidate, ctx)) {
4461 new_lease = createLease4(ctx, candidate, callout_status);
4465 if (exist_lease->expired() &&
4466 (check_reservation_first || !addressReserved(candidate, ctx))) {
4468 new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
4477 if (ctx.
callout_handle_ && (callout_status != CalloutHandle::NEXT_STEP_CONTINUE)) {
4486 subnet = subnet->getNextSubnet(original_subnet, ctx.
query_->getClasses());
4498 .arg(ctx.
query_->getLabel())
4499 .arg(network->getName())
4500 .arg(subnets_with_unavail_leases)
4501 .arg(subnets_with_unavail_pools);
4502 StatsMgr::instance().addValue(
"v4-allocation-fail-shared-network",
4503 static_cast<int64_t>(1));
4504 StatsMgr::instance().addValue(
4505 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4506 "v4-allocation-fail-shared-network"),
4507 static_cast<int64_t>(1));
4512 .arg(ctx.
query_->getLabel())
4515 .arg(ctx.
subnet_->getSharedNetworkName());
4516 StatsMgr::instance().addValue(
"v4-allocation-fail-subnet",
4517 static_cast<int64_t>(1));
4518 StatsMgr::instance().addValue(
4519 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4520 "v4-allocation-fail-subnet"),
4521 static_cast<int64_t>(1));
4523 if (total_attempts == 0) {
4529 .arg(ctx.
query_->getLabel());
4530 StatsMgr::instance().addValue(
"v4-allocation-fail-no-pools",
4531 static_cast<int64_t>(1));
4532 StatsMgr::instance().addValue(
4533 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4534 "v4-allocation-fail-no-pools"),
4535 static_cast<int64_t>(1));
4542 .arg(ctx.
query_->getLabel())
4543 .arg(total_attempts);
4544 StatsMgr::instance().addValue(
"v4-allocation-fail",
4545 static_cast<int64_t>(1));
4546 StatsMgr::instance().addValue(
4547 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4548 "v4-allocation-fail"),
4549 static_cast<int64_t>(1));
4553 if (!classes.
empty()) {
4555 .arg(ctx.
query_->getLabel())
4557 StatsMgr::instance().addValue(
"v4-allocation-fail-classes",
4558 static_cast<int64_t>(1));
4559 StatsMgr::instance().addValue(
4560 StatsMgr::generateName(
"subnet", ctx.
subnet_->getID(),
4561 "v4-allocation-fail-classes"),
4562 static_cast<int64_t>(1));
4569 AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
4571 bool changed =
false;
4572 if (lease->subnet_id_ != ctx.
subnet_->getID()) {
4574 lease->subnet_id_ = ctx.
subnet_->getID();
4576 if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
4578 (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
4583 if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
4587 }
else if (lease->client_id_) {
4591 lease->cltt_ = time(NULL);
4597 if (lease->valid_lft_ < lease->current_valid_lft_) {
4621 bool changed =
false;
4624 if (!ctx.
subnet_->getStoreExtendedInfo()) {
4639 ElementPtr extended_info = Element::createMap();
4640 extended_info->set(
"relay-agent-info", relay_agent);
4644 if (lease->getContext()) {
4645 user_context = UserContext::toElement(lease->getContext());
4647 user_context = Element::createMap();
4652 if (!old_extended_info || (*old_extended_info != *extended_info)) {
4654 user_context->set(
"ISC", extended_info);
4658 lease->setContext(user_context);
4666 bool changed =
false;
4669 if (!ctx.
subnet_->getStoreExtendedInfo()) {
4674 if (ctx.
query_->relay_info_.empty()) {
4688 ElementPtr relay_list = Element::createList();
4689 for (
auto relay : ctx.
query_->relay_info_) {
4690 ElementPtr relay_elem = Element::createMap();
4698 if (!relay.options_.empty()) {
4703 const uint8_t* cp =
static_cast<const uint8_t*
>(buf.
getData());
4704 std::vector<uint8_t>bytes;
4705 std::stringstream ss;
4713 relay_list->add(relay_elem);
4717 ElementPtr extended_info = Element::createMap();
4718 extended_info->set(
"relays", relay_list);
4722 if (lease->getContext()) {
4723 user_context = UserContext::toElement(lease->getContext());
4725 user_context = Element::createMap();
4730 if (!old_extended_info || (*old_extended_info != *extended_info)) {
4732 user_context->set(
"ISC", extended_info);
4736 lease->setContext(user_context);
4742 AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
4745 lease->reuseable_valid_lft_ = 0;
4761 if (lease->cltt_ < lease->current_cltt_) {
4765 uint32_t age = lease->cltt_ - lease->current_cltt_;
4767 if (age >= lease->current_valid_lft_) {
4772 uint32_t max_age = 0;
4773 if (!subnet->getCacheMaxAge().unspecified()) {
4774 max_age = subnet->getCacheMaxAge().get();
4775 if ((max_age == 0) || (age > max_age)) {
4781 if (!subnet->getCacheThreshold().unspecified()) {
4782 double threshold = subnet->getCacheThreshold().get();
4783 if ((threshold <= 0.) || (threshold > 1.)) {
4786 max_age = lease->valid_lft_ * threshold;
4787 if (age > max_age) {
4798 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
4802 AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
4803 uint32_t current_preferred_lft,
4806 lease->reuseable_valid_lft_ = 0;
4807 lease->reuseable_preferred_lft_ = 0;
4817 if (lease->cltt_ < lease->current_cltt_) {
4821 uint32_t age = lease->cltt_ - lease->current_cltt_;
4823 if (age >= lease->current_valid_lft_) {
4828 uint32_t max_age = 0;
4829 if (!subnet->getCacheMaxAge().unspecified()) {
4830 max_age = subnet->getCacheMaxAge().get();
4831 if ((max_age == 0) || (age > max_age)) {
4837 if (!subnet->getCacheThreshold().unspecified()) {
4838 double threshold = subnet->getCacheThreshold().get();
4839 if ((threshold <= 0.) || (threshold > 1.)) {
4842 max_age = lease->valid_lft_ * threshold;
4843 if (age > max_age) {
4855 (current_preferred_lft == 0)) {
4857 lease->reuseable_preferred_lft_ = current_preferred_lft;
4858 }
else if (current_preferred_lft > age) {
4859 lease->reuseable_preferred_lft_ = current_preferred_lft - age;
4867 lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
#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
std::string toText(const std::string &separator=", ") const
Returns all class names as text.
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)
A generic exception that is thrown when a function is not implemented.
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.
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
static std::string typeToText(Type type)
returns text representation of a lease type
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...
static isc::asiolink::IOAddress increaseAddress(const isc::asiolink::IOAddress &address, bool prefix, const uint8_t prefix_len)
Returns the next address or prefix.
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
bool updateLease6ExtendedInfo(const Lease6Ptr &lease, const ClientContext6 &ctx) const
Stores additional client query parameters on a V6 lease.
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.
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
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
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED
IPv6 reservation for a host.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ERROR
AllocEngine(AllocType engine_type, uint64_t attempts, bool ipv6=true)
Constructor.
const_iterator cbegin() const
Iterator 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.
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.
An exception that is thrown when allocation module fails (e.g.
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.
AllocType
Specifies allocation type.
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.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
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.
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
Random allocator that picks address randomly.
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.
A generic exception that is thrown when an unexpected error condition occurs.
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.
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...
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.
Address/prefix allocator that iterates over all addresses.
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.
bool isV6() const
Convenience function to check for an IPv6 address.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv4 leases.
the lease contains temporary IPv6 address
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
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)
boost::shared_ptr< Allocator > AllocatorPtr
defines a pointer to allocator
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_COMPLETE
Address/prefix allocator that gets an address based on a hash.
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
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA
HashedAllocator(Lease::Type type)
Default constructor (does nothing)
a common structure for IPv4 and IPv6 leases
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED
Type
Type of lease or pool.
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
Base class for all address/prefix allocation algorithms.
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
Iterator 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.
Lease::Type pool_type_
Defines pool type allocation.
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
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.
static isc::asiolink::IOAddress increasePrefix(const isc::asiolink::IOAddress &prefix, const uint8_t prefix_len)
Returns the next prefix.
std::pair< IPv6Resrv::Type, IPv6Resrv > IPv6ResrvTuple
HWAddrPtr hwaddr_
HW address from the DHCP message.
The IOAddress class represents an IP addresses (version agnostic)
static LeaseMgr & instance()
Return current lease manager.
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.
RandomAllocator(Lease::Type type)
Default constructor (does nothing)
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.