36#include <boost/foreach.hpp> 
   37#include <boost/make_shared.hpp> 
   54namespace ph = std::placeholders;
 
   59struct AllocEngineHooks {
 
   60    int hook_index_lease4_select_; 
 
   61    int hook_index_lease4_renew_;  
 
   62    int hook_index_lease4_expire_; 
 
   63    int hook_index_lease4_recover_;
 
   64    int hook_index_lease6_select_; 
 
   65    int hook_index_lease6_renew_;  
 
   66    int hook_index_lease6_rebind_; 
 
   67    int hook_index_lease6_expire_; 
 
   68    int hook_index_lease6_recover_;
 
   88AllocEngineHooks 
Hooks;
 
   96    : attempts_(attempts), incomplete_v4_reclamations_(0),
 
   97      incomplete_v6_reclamations_(0) {
 
  100    hook_index_lease4_select_ = 
Hooks.hook_index_lease4_select_;
 
  101    hook_index_lease6_select_ = 
Hooks.hook_index_lease6_select_;
 
 
  128    if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
 
  133                reserved.push_back(host);
 
  144        reserved.insert(reserved.end(), hosts.begin(), hosts.end());
 
  163              const IOAddress& address, 
bool check_subnet) {
 
  167    auto const& classes = ctx.
query_->getClasses();
 
  169    while (current_subnet) {
 
  170        if (current_subnet->clientSupported(classes)) {
 
  172                if (current_subnet->inPool(lease_type, address)) {
 
  176                if (current_subnet->inPool(lease_type, address, classes)) {
 
  182        current_subnet = current_subnet->getNextSubnet(ctx.
subnet_);
 
  209                                            const std::string& hostname,
 
  210                                            const bool fake_allocation,
 
  218      ias_(), ddns_params_() {
 
 
  234                   const uint8_t prefix_len,
 
  235                   const uint32_t preferred,
 
  236                   const uint32_t valid) {
 
 
  246    addHint(iaaddr->getAddress(), 128,
 
  247            iaaddr->getPreferred(), iaaddr->getValid());
 
 
  256    addHint(iaprefix->getAddress(), iaprefix->getLength(),
 
  257            iaprefix->getPreferred(), iaprefix->getValid());
 
 
  263                          const uint8_t prefix_len) {
 
 
  270                         const uint8_t prefix_len)
 const {
 
 
  278                     const uint8_t prefix_len) {
 
 
  286    return (
static_cast<bool> 
 
  293    if (subnet && subnet->getReservationsInSubnet()) {
 
  294        auto host = 
hosts_.find(subnet->getID());
 
  295        if (host != 
hosts_.cend()) {
 
  296            return (host->second);
 
 
  306    if (subnet && 
subnet_->getReservationsGlobal()) {
 
  307        auto host = 
hosts_.find(SUBNET_ID_GLOBAL);
 
  308        if (host != 
hosts_.cend()) {
 
  309            return (host->second);
 
 
  319    return (ghost && ghost->hasReservation(resv));
 
 
  325    if (ddns_params_ && 
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
 
  326        return (ddns_params_);
 
  332        return (ddns_params_);
 
 
  351        !subnet->getReservationsInSubnet()) {
 
  357        subnet->getReservationsGlobal()) {
 
  360            ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
 
  363            if (!subnet->getReservationsInSubnet()) {
 
  369    std::map<SubnetID, ConstHostPtr> host_map;
 
  371    subnet->getSharedNetwork(network);
 
  380    const bool use_single_query = network &&
 
  384    if (use_single_query) {
 
  388                                                                   id_pair.second.size());
 
  392            for (
auto const& host : hosts) {
 
  393                if (host->getIPv6SubnetID() != SUBNET_ID_GLOBAL) {
 
  394                    host_map[host->getIPv6SubnetID()] = host;
 
  400    auto const& classes = ctx.
query_->getClasses();
 
  407        if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
 
  410            if (use_single_query) {
 
  411                if (host_map.count(subnet->getID()) > 0) {
 
  412                    ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
 
  420                                                                 id_pair.second.size());
 
  423                        ctx.
hosts_[subnet->getID()] = host;
 
  433        subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
 
  439    for (
auto const& host : ctx.
hosts_) {
 
  440        host.second->encapsulateOptions();
 
 
  450                                        &id_pair.second[0], id_pair.second.size());
 
 
  484            for (
auto const& l : all_leases) {
 
  486                    ((l)->subnet_id_ == subnet->getID())) {
 
  491            subnet = subnet->getNextSubnet(ctx.
subnet_);
 
  511        if (leases.empty() && !ctx.
hosts_.empty()) {
 
  515                .arg(ctx.
query_->getLabel());
 
  520            allocateReservedLeases6(ctx, leases);
 
  522            leases = updateLeaseData(ctx, leases);
 
  537        } 
else if (!leases.empty() && ctx.
hosts_.empty()) {
 
  541                .arg(ctx.
query_->getLabel());
 
  545            removeNonmatchingReservedLeases6(ctx, leases);
 
  547            leases = updateLeaseData(ctx, leases);
 
  556        } 
else if (!leases.empty() && !ctx.
hosts_.empty()) {
 
  560                .arg(ctx.
query_->getLabel());
 
  564            allocateReservedLeases6(ctx, leases);
 
  576            removeNonmatchingReservedLeases6(ctx, leases);
 
  585            removeNonreservedLeases6(ctx, leases);
 
  590            leases = updateLeaseData(ctx, leases);
 
  603        if (leases.empty()) {
 
  617                .arg(ctx.
query_->getLabel());
 
  619            leases = allocateUnreservedLeases6(ctx);
 
  622        if (!leases.empty()) {
 
  626            for (
auto const& lease : leases) {
 
  640            .arg(ctx.
query_->getLabel())
 
 
  653    uint8_t hint_prefix_length = 128;
 
  654    if (!ctx.currentIA().hints_.empty()) {
 
  656        hint = ctx.currentIA().hints_[0].getAddress();
 
  657        hint_prefix_length = ctx.currentIA().hints_[0].getPrefixLength();
 
  666    uint64_t total_attempts = 0;
 
  670    uint64_t subnets_with_unavail_leases = 0;
 
  673    uint64_t subnets_with_unavail_pools = 0;
 
  683    bool search_hint_lease = 
true;
 
  690        if (hint_prefix_length == 128) {
 
  691            hint_prefix_length = 0;
 
  693        if (!hint_prefix_length) {
 
  701    Lease6Ptr lease = allocateBestMatch(ctx, hint_lease, search_hint_lease,
 
  702                                        hint, hint_prefix_length, subnet,
 
  703                                        network, total_attempts,
 
  704                                        subnets_with_unavail_leases,
 
  705                                        subnets_with_unavail_pools,
 
  706                                        callout_status, prefix_length_match);
 
  714        lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
 
  715                                  hint_prefix_length, subnet, network,
 
  716                                  total_attempts, subnets_with_unavail_leases,
 
  717                                  subnets_with_unavail_pools, callout_status,
 
  718                                  prefix_length_match);
 
  727        lease = allocateBestMatch(ctx, hint_lease, search_hint_lease, hint,
 
  728                                  hint_prefix_length, subnet, network,
 
  729                                  total_attempts, subnets_with_unavail_leases,
 
  730                                  subnets_with_unavail_pools, callout_status,
 
  731                                  prefix_length_match);
 
  735        leases.push_back(lease);
 
  739    auto const& classes = ctx.query_->getClasses();
 
  745            .arg(ctx.query_->getLabel())
 
  746            .arg(network->getName())
 
  747            .arg(subnets_with_unavail_leases)
 
  748            .arg(subnets_with_unavail_pools);
 
  750                                      static_cast<int64_t
>(1));
 
  753                                   "v6-allocation-fail-shared-network"),
 
  754                                   static_cast<int64_t
>(1));
 
  758        std::string shared_network = ctx.subnet_->getSharedNetworkName();
 
  759        if (shared_network.empty()) {
 
  760            shared_network = 
"(none)";
 
  763            .arg(ctx.query_->getLabel())
 
  764            .arg(ctx.subnet_->toText())
 
  765            .arg(ctx.subnet_->getID())
 
  766            .arg(shared_network);
 
  768                                      static_cast<int64_t
>(1));
 
  771                                   "v6-allocation-fail-subnet"),
 
  772                                   static_cast<int64_t
>(1));
 
  774    if (total_attempts == 0) {
 
  780            .arg(ctx.query_->getLabel());
 
  782                                      static_cast<int64_t
>(1));
 
  785                                   "v6-allocation-fail-no-pools"),
 
  786                                   static_cast<int64_t
>(1));
 
  793            .arg(ctx.query_->getLabel())
 
  794            .arg(total_attempts);
 
  796                                      static_cast<int64_t
>(1));
 
  799                                   "v6-allocation-fail"),
 
  800                                   static_cast<int64_t
>(1));
 
  803    if (!classes.empty()) {
 
  805            .arg(ctx.query_->getLabel())
 
  806            .arg(classes.toText());
 
  808                                      static_cast<int64_t
>(1));
 
  811                                   "v6-allocation-fail-classes"),
 
  812                                   static_cast<int64_t
>(1));
 
  822                               bool& search_hint_lease,
 
  823                               const isc::asiolink::IOAddress& hint,
 
  824                               uint8_t hint_prefix_length,
 
  827                               uint64_t& total_attempts,
 
  828                               uint64_t& subnets_with_unavail_leases,
 
  829                               uint64_t& subnets_with_unavail_pools,
 
  832    auto const& classes = ctx.query_->getClasses();
 
  837    if (!search_hint_lease) {
 
  838        usable_hint_lease = hint_lease;
 
  840    for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
 
  841        if (!subnet->clientSupported(classes)) {
 
  845        ctx.subnet_ = subnet;
 
  849        pool = boost::dynamic_pointer_cast<Pool6>
 
  850            (subnet->getPool(ctx.currentIA().type_, classes, hint));
 
  853        if (!pool || !pool->clientSupported(classes)) {
 
  859                                          hint_prefix_length)) {
 
  863        bool in_subnet = subnet->getReservationsInSubnet();
 
  866        if (search_hint_lease) {
 
  867            search_hint_lease = 
false;
 
  869            usable_hint_lease = hint_lease;
 
  871        if (!usable_hint_lease) {
 
  883                (!subnet->getReservationsOutOfPool() ||
 
  884                 !subnet->inPool(ctx.currentIA().type_, hint))) {
 
  885                hosts = getIPv6Resrv(subnet->getID(), hint);
 
  895                Lease6Ptr new_lease = createLease6(ctx, hint, pool->getLength(), callout_status);
 
  908                    .arg(ctx.query_->getLabel())
 
  912        } 
else if (usable_hint_lease->expired() &&
 
  922                (!subnet->getReservationsOutOfPool() ||
 
  923                 !subnet->inPool(ctx.currentIA().type_, hint))) {
 
  924                hosts = getIPv6Resrv(subnet->getID(), hint);
 
  932                Lease6Ptr old_lease(
new Lease6(*usable_hint_lease));
 
  933                ctx.currentIA().old_leases_.push_back(old_lease);
 
  936                Lease6Ptr lease = reuseExpiredLease(usable_hint_lease, ctx,
 
  946                    .arg(ctx.query_->getLabel())
 
  958    if (!check_reservation_first) {
 
  972    original_subnet->getSharedNetwork(network);
 
  979        original_subnet = network->getPreferredSubnet(original_subnet, ctx.currentIA().type_);
 
  982    ctx.subnet_ = subnet = original_subnet;
 
  984    for (; subnet; subnet = subnet->getNextSubnet(original_subnet)) {
 
  985        if (!subnet->clientSupported(classes)) {
 
  996            subnet->getPoolCapacity(ctx.currentIA().type_,
 
 1007            (attempts_ == 0 || possible_attempts < attempts_) ?
 
 1011        if (max_attempts > 0) {
 
 1014            ++subnets_with_unavail_leases;
 
 1018            ++subnets_with_unavail_pools;
 
 1022        bool in_subnet = subnet->getReservationsInSubnet();
 
 1023        bool out_of_pool = subnet->getReservationsOutOfPool();
 
 1028        if (ctx.callout_handle_) {
 
 1032        for (uint64_t i = 0; i < max_attempts; ++i) {
 
 1035            auto allocator = subnet->getAllocator(ctx.currentIA().type_);
 
 1040            uint8_t prefix_len = 128;
 
 1042                candidate = allocator->pickPrefix(classes, pool, ctx.duid_,
 
 1043                                                  prefix_length_match, hint,
 
 1044                                                  hint_prefix_length);
 
 1046                    prefix_len = pool->getLength();
 
 1049                candidate = allocator->pickAddress(classes, ctx.duid_, hint);
 
 1058            if (check_reservation_first && in_subnet && !out_of_pool) {
 
 1059                auto hosts = getIPv6Resrv(subnet->getID(), candidate);
 
 1060                if (!hosts.empty()) {
 
 1068            ResourceHandler resource_handler;
 
 1070                !resource_handler.
tryLock(ctx.currentIA().type_, candidate)) {
 
 1083                if (!check_reservation_first && in_subnet && !out_of_pool) {
 
 1084                    auto hosts = getIPv6Resrv(subnet->getID(), candidate);
 
 1085                    if (!hosts.empty()) {
 
 1094                ctx.subnet_ = subnet;
 
 1095                Lease6Ptr new_lease = createLease6(ctx, candidate, prefix_len, callout_status);
 
 1099                    ctx.currentIA().old_leases_.clear();
 
 1103                } 
else if (ctx.callout_handle_ &&
 
 1112            } 
else if (existing->expired() &&
 
 1115                if (!check_reservation_first && in_subnet && !out_of_pool) {
 
 1116                    auto hosts = getIPv6Resrv(subnet->getID(), candidate);
 
 1117                    if (!hosts.empty()) {
 
 1125                Lease6Ptr old_lease(
new Lease6(*existing));
 
 1126                ctx.currentIA().old_leases_.push_back(old_lease);
 
 1128                ctx.subnet_ = subnet;
 
 1129                existing = reuseExpiredLease(existing, ctx, prefix_len,
 
 1144    if (ctx.hosts_.empty()) {
 
 1147            .arg(ctx.query_->getLabel());
 
 1158    for (
auto const& lease : existing_leases) {
 
 1159        if ((lease->valid_lft_ != 0)) {
 
 1160            if ((ctx.hosts_.count(lease->subnet_id_) > 0) &&
 
 1161                ctx.hosts_[lease->subnet_id_]->hasReservation(
makeIPv6Resrv(*lease))) {
 
 1166                    .arg(ctx.query_->getLabel())
 
 1167                    .arg(lease->typeToText(lease->type_))
 
 1168                    .arg(lease->addr_.toText());
 
 1174                if (!ctx.host_subnet_) {
 
 1176                    ctx.subnet_->getSharedNetwork(network);
 
 1181                        ctx.host_subnet_ = network->getSubnet(lease->subnet_id_);
 
 1189                        if (host && !host->getHostname().empty()) {
 
 1196                                qualifyName(host->getHostname(), *ctx.getDdnsParams(),
 
 1197                                            static_cast<bool>(fqdn));
 
 1211    auto const& classes = ctx.query_->getClasses();
 
 1213         subnet = subnet->getNextSubnet(ctx.subnet_)) {
 
 1215        SubnetID subnet_id = subnet->getID();
 
 1218        if (!subnet->clientSupported(classes) || ctx.hosts_.count(subnet_id) == 0) {
 
 1224        bool in_subnet = subnet->getReservationsInSubnet();
 
 1228        BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
 
 1230            const IOAddress& addr = type_lease_tuple.second.getPrefix();
 
 1231            uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
 
 1235            if (ctx.isAllocated(addr, prefix_len)) {
 
 1244                (subnet->getReservationsOutOfPool() &&
 
 1245                 subnet->inPool(ctx.currentIA().type_, addr))) {
 
 1257                ctx.subnet_ = subnet;
 
 1259                if (!ctx.host_subnet_) {
 
 1260                    ctx.host_subnet_ = subnet;
 
 1261                    if (!host->getHostname().empty()) {
 
 1275                            qualifyName(host->getHostname(), *ctx.getDdnsParams(),
 
 1276                                        static_cast<bool>(fqdn));
 
 1282                Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
 
 1285                existing_leases.push_back(lease);
 
 1290                        .arg(ctx.query_->getLabel());
 
 1294                        .arg(
static_cast<int>(prefix_len))
 
 1295                        .arg(ctx.query_->getLabel());
 
 1313    allocateGlobalReservedLeases6(ctx, existing_leases);
 
 1328    for (
auto const& lease : existing_leases) {
 
 1329        if ((lease->valid_lft_ != 0) &&
 
 1335                    .arg(ctx.query_->getLabel())
 
 1336                    .arg(lease->typeToText(lease->type_))
 
 1337                    .arg(lease->addr_.toText());
 
 1343            if (!ghost->getHostname().empty()) {
 
 1350                                    qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
 
 1351                                                static_cast<bool>(fqdn));
 
 1366    const IPv6ResrvRange& reservs = ghost->getIPv6Reservations(type);
 
 1367    BOOST_FOREACH(
auto const& type_lease_tuple, reservs) {
 
 1369        const IOAddress& addr = type_lease_tuple.second.getPrefix();
 
 1370        uint8_t prefix_len = type_lease_tuple.second.getPrefixLen();
 
 1374        if (ctx.isAllocated(addr, prefix_len)) {
 
 1386                bool valid_subnet = 
false;
 
 1387                auto subnet = ctx.subnet_;
 
 1389                    if (subnet->inRange(addr)) {
 
 1390                        valid_subnet = 
true;
 
 1394                    subnet = subnet->getNextSubnet(ctx.subnet_);
 
 1397                if (!valid_subnet) {
 
 1400                              .arg(ctx.query_->getLabel())
 
 1406                ctx.subnet_ = subnet;
 
 1409            if (!ghost->getHostname().empty()) {
 
 1423                                qualifyName(ghost->getHostname(), *ctx.getDdnsParams(),
 
 1424                                            static_cast<bool>(fqdn));
 
 1429            Lease6Ptr lease = createLease6(ctx, addr, prefix_len, callout_status);
 
 1432            existing_leases.push_back(lease);
 
 1437                        .arg(ctx.query_->getLabel());
 
 1441                        .arg(
static_cast<int>(prefix_len))
 
 1442                        .arg(ctx.query_->getLabel());
 
 1460AllocEngine::removeNonmatchingReservedLeases6(
ClientContext6& ctx,
 
 1463    if (existing_leases.empty() || !ctx.subnet_) {
 
 1468    if (!ctx.subnet_->getReservationsInSubnet() &&
 
 1469        !ctx.subnet_->getReservationsGlobal()) {
 
 1470        removeNonmatchingReservedNoHostLeases6(ctx, existing_leases);
 
 1479    for (
auto const& candidate : 
copy) {
 
 1483        if ((ctx.hasGlobalReservation(resv)) ||
 
 1484            ((ctx.hosts_.count(candidate->subnet_id_) > 0) &&
 
 1485             (ctx.hosts_[candidate->subnet_id_]->hasReservation(resv)))) {
 
 1494        auto hosts = getIPv6Resrv(ctx.subnet_->getID(), candidate->addr_);
 
 1499        if (hosts.empty() && inAllowedPool(ctx, candidate->type_,
 
 1500                                           candidate->addr_, 
false)) {
 
 1504        if (!hosts.empty()) {
 
 1507            if (hosts.size() == 1) {
 
 1510                        .arg(ctx.query_->getLabel())
 
 1511                        .arg(candidate->addr_.
toText())
 
 1512                        .arg(ctx.duid_->toText())
 
 1513                        .arg(hosts.front()->getIdentifierAsText());
 
 1516                        .arg(ctx.query_->getLabel())
 
 1517                        .arg(candidate->addr_.
toText())
 
 1518                        .arg(
static_cast<int>(candidate->prefixlen_))
 
 1519                        .arg(ctx.duid_->toText())
 
 1520                        .arg(hosts.front()->getIdentifierAsText());
 
 1525                        .arg(ctx.query_->getLabel())
 
 1526                        .arg(candidate->addr_.
toText())
 
 1527                        .arg(ctx.duid_->toText())
 
 1531                        .arg(ctx.query_->getLabel())
 
 1532                        .arg(candidate->addr_.
toText())
 
 1533                        .arg(
static_cast<int>(candidate->prefixlen_))
 
 1534                        .arg(ctx.duid_->toText())
 
 1555                                   "assigned-nas" : 
"assigned-pds"),
 
 1556            static_cast<int64_t
>(-1));
 
 1560            auto const& pool = subnet->getPool(ctx.currentIA().type_, candidate->addr_, 
false);
 
 1565                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 1567                                                                  "assigned-nas" : 
"assigned-pds")),
 
 1568                    static_cast<int64_t
>(-1));
 
 1578        ctx.currentIA().old_leases_.push_back(candidate);
 
 1581        removeLeases(existing_leases, candidate->addr_);
 
 1586AllocEngine::removeNonmatchingReservedNoHostLeases6(
ClientContext6& ctx,
 
 1593    for (
auto const& candidate : 
copy) {
 
 1597        if (inAllowedPool(ctx, candidate->type_,
 
 1598                          candidate->addr_, 
false)) {
 
 1616                                   "assigned-nas" : 
"assigned-pds"),
 
 1617            static_cast<int64_t
>(-1));
 
 1621            auto const& pool = subnet->getPool(candidate->type_, candidate->addr_, 
false);
 
 1626                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 1628                                                                  "assigned-nas" : 
"assigned-pds")),
 
 1629                    static_cast<int64_t
>(-1));
 
 1634        ctx.currentIA().old_leases_.push_back(candidate);
 
 1637        removeLeases(existing_leases, candidate->addr_);
 
 1642AllocEngine::removeLeases(
Lease6Collection& container, 
const asiolink::IOAddress& addr) {
 
 1644    bool removed = 
false;
 
 1645    for (Lease6Collection::iterator lease = container.begin();
 
 1646         lease != container.end(); ++lease) {
 
 1647        if ((*lease)->addr_ == addr) {
 
 1654    container.erase(std::remove(container.begin(), container.end(), 
Lease6Ptr()),
 
 1665    int total = existing_leases.size();
 
 1672    for (Lease6Collection::iterator lease = existing_leases.begin();
 
 1673         lease != existing_leases.end(); ++lease) {
 
 1677        if (ctx.hasGlobalReservation(resv) ||
 
 1678            ((ctx.hosts_.count((*lease)->subnet_id_) > 0) &&
 
 1679             (ctx.hosts_[(*lease)->subnet_id_]->hasReservation(resv)))) {
 
 1701                                   "assigned-nas" : 
"assigned-pds"),
 
 1702            static_cast<int64_t
>(-1));
 
 1706            auto const& pool = subnet->getPool(ctx.currentIA().type_, (*lease)->addr_, 
false);
 
 1711                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 1713                                                                  "assigned-nas" : 
"assigned-pds")),
 
 1714                    static_cast<int64_t
>(-1));
 
 1721        ctx.currentIA().old_leases_.push_back(*lease);
 
 1736    existing_leases.erase(std::remove(existing_leases.begin(),
 
 1737        existing_leases.end(), 
Lease6Ptr()), existing_leases.end());
 
 1745    if (!expired->expired()) {
 
 1746        isc_throw(BadValue, 
"Attempt to recycle lease that is still valid");
 
 1750        isc_throw(BadValue, 
"Attempt to recycle registered address");
 
 1757    if (!ctx.fake_allocation_) {
 
 1761        reclaimExpiredLease(expired, ctx.callout_handle_);
 
 1765    expired->iaid_ = ctx.currentIA().iaid_;
 
 1766    expired->duid_ = ctx.duid_;
 
 1769    getLifetimes6(ctx, expired->preferred_lft_, expired->valid_lft_);
 
 1770    expired->reuseable_valid_lft_ = 0;
 
 1772    expired->cltt_ = time(NULL);
 
 1773    expired->subnet_id_ = ctx.subnet_->getID();
 
 1774    expired->hostname_ = ctx.hostname_;
 
 1775    expired->fqdn_fwd_ = ctx.fwd_dns_update_;
 
 1776    expired->fqdn_rev_ = ctx.rev_dns_update_;
 
 1777    expired->prefixlen_ = prefix_len;
 
 1782        .arg(ctx.query_->getLabel())
 
 1783        .arg(expired->toText());
 
 1786    if (ctx.callout_handle_ &&
 
 1793        ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
 
 1796        ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
 
 1801        ctx.callout_handle_->setArgument(
"query6", ctx.query_);
 
 1804        ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
 
 1807        ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
 
 1810        ctx.callout_handle_->setArgument(
"lease6", expired);
 
 1815        callout_status = ctx.callout_handle_->getStatus();
 
 1832        ctx.callout_handle_->getArgument(
"lease6", expired);
 
 1835    if (!ctx.fake_allocation_) {
 
 1839        auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, expired->addr_, 
false);
 
 1841            expired->pool_id_ = pool->getID();
 
 1849        if (ctx.subnet_->inPool(ctx.currentIA().type_, expired->addr_)) {
 
 1853                                       "assigned-nas" : 
"assigned-pds"),
 
 1854                static_cast<int64_t
>(1));
 
 1859                                       "cumulative-assigned-nas" : 
"cumulative-assigned-pds"),
 
 1860                static_cast<int64_t
>(1));
 
 1866                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 1868                                                                  "assigned-nas" : 
"assigned-pds")),
 
 1869                    static_cast<int64_t
>(1));
 
 1874                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 1876                                                                  "cumulative-assigned-nas" : 
"cumulative-assigned-pds")),
 
 1877                    static_cast<int64_t
>(1));
 
 1881                                          "cumulative-assigned-nas" : 
"cumulative-assigned-pds",
 
 1882                                          static_cast<int64_t
>(1));
 
 1901    if (!classes.
empty()) {
 
 1908        for (
auto const& name : classes) {
 
 1911                (cl && (!cl->getPreferred().unspecified()))) {
 
 1912                candidate_preferred = cl->getPreferred();
 
 1917                (cl && (!cl->getValid().unspecified()))) {
 
 1918                candidate_valid = cl->getValid();
 
 1921            if (have_both == 2) {
 
 1928    if (!candidate_preferred) {
 
 1929        candidate_preferred = ctx.
subnet_->getPreferred();
 
 1933    if (!candidate_valid) {
 
 1934        candidate_valid = ctx.
subnet_->getValid();
 
 1938    preferred = candidate_preferred;
 
 1939    valid = candidate_valid;
 
 1954    if (!preferred || preferred > valid) {
 
 1955        preferred = ((valid * 5)/8);
 
 1958                .arg(ctx.
query_->getLabel())
 
 
 1972    uint32_t preferred = 0;
 
 1977                               ctx.currentIA().iaid_, preferred,
 
 1978                               valid, ctx.subnet_->getID(),
 
 1979                               ctx.hwaddr_, prefix_len));
 
 1981    lease->fqdn_fwd_ = ctx.fwd_dns_update_;
 
 1982    lease->fqdn_rev_ = ctx.rev_dns_update_;
 
 1983    lease->hostname_ = ctx.hostname_;
 
 1986    if (ctx.callout_handle_ &&
 
 2001        ctx.callout_handle_->setArgument(
"query6", ctx.query_);
 
 2004        ctx.callout_handle_->setArgument(
"subnet6", ctx.subnet_);
 
 2007        ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
 
 2010        ctx.callout_handle_->setArgument(
"lease6", lease);
 
 2015        callout_status = ctx.callout_handle_->getStatus();
 
 2027        ctx.callout_handle_->getArgument(
"lease6", lease);
 
 2030    if (!ctx.fake_allocation_) {
 
 2034        auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, 
false);
 
 2036            lease->pool_id_ = pool->getID();
 
 2045            if (ctx.subnet_->inPool(ctx.currentIA().type_, addr)) {
 
 2049                                           "assigned-nas" : 
"assigned-pds"),
 
 2050                    static_cast<int64_t
>(1));
 
 2055                                           "cumulative-assigned-nas" : 
"cumulative-assigned-pds"),
 
 2056                    static_cast<int64_t
>(1));
 
 2062                                                                      "pool" : 
"pd-pool", pool->getID(),
 
 2064                                                                      "assigned-nas" : 
"assigned-pds")),
 
 2065                        static_cast<int64_t
>(1));
 
 2070                                                                      "pool" : 
"pd-pool", pool->getID(),
 
 2072                                                                      "cumulative-assigned-nas" : 
"cumulative-assigned-pds")),
 
 2073                        static_cast<int64_t
>(1));
 
 2077                                              "cumulative-assigned-nas" : 
"cumulative-assigned-pds",
 
 2078                                              static_cast<int64_t
>(1));
 
 2082            ctx.currentIA().addNewResource(addr, prefix_len);
 
 2121            for (
auto const& l : leases_subnet) {
 
 2123                    leases.push_back(l);
 
 2126            subnet = subnet->getNextSubnet(ctx.
subnet_);
 
 2129        if (!leases.empty()) {
 
 2132                .arg(ctx.
query_->getLabel());
 
 2136            removeNonmatchingReservedLeases6(ctx, leases);
 
 2139        if (!ctx.
hosts_.empty()) {
 
 2143                .arg(ctx.
query_->getLabel());
 
 2146            allocateReservedLeases6(ctx, leases);
 
 2152            removeNonreservedLeases6(ctx, leases);
 
 2159        if (leases.empty()) {
 
 2163                .arg(ctx.
query_->getLabel());
 
 2165            leases = allocateUnreservedLeases6(ctx);
 
 2169        for (
auto const& l : leases) {
 
 2177                .arg(ctx.
query_->getLabel())
 
 2178                .arg(l->typeToText(l->type_))
 
 2180            extendLease6(ctx, l);
 
 2183        if (!leases.empty()) {
 
 2187            for (
auto const& lease : leases) {
 
 2202            .arg(ctx.
query_->getLabel())
 
 
 2212    if (!lease || !ctx.subnet_) {
 
 2218    if (ctx.subnet_->getID() != lease->subnet_id_) {
 
 2220        ctx.subnet_->getSharedNetwork(network);
 
 2223                network->getSubnet(
SubnetID(lease->subnet_id_));
 
 2227                ctx.subnet_ = subnet;
 
 2235        (((lease->type_ != 
Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) ||
 
 2236        !ctx.subnet_->clientSupported(ctx.query_->getClasses()))) {
 
 2253                                   "assigned-nas" : 
"assigned-pds"),
 
 2254            static_cast<int64_t
>(-1));
 
 2256        auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, 
false);
 
 2261                                                              "pool" : 
"pd-pool", pool->getID(),
 
 2263                                                              "assigned-nas" : 
"assigned-pds")),
 
 2264                static_cast<int64_t
>(-1));
 
 2268        ctx.currentIA().old_leases_.push_back(lease);
 
 2275        .arg(ctx.query_->getLabel())
 
 2276        .arg(lease->toText());
 
 2281    bool changed = 
false;
 
 2284    uint32_t current_preferred_lft = lease->preferred_lft_;
 
 2285    getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
 
 2288    if ((lease->preferred_lft_ != current_preferred_lft) ||
 
 2289        (lease->valid_lft_ != lease->current_valid_lft_)) {
 
 2293    lease->cltt_ = time(NULL);
 
 2294    if ((lease->fqdn_fwd_ != ctx.fwd_dns_update_) ||
 
 2295        (lease->fqdn_rev_ != ctx.rev_dns_update_) ||
 
 2296        (lease->hostname_ != ctx.hostname_)) {
 
 2298        lease->hostname_ = ctx.hostname_;
 
 2299        lease->fqdn_fwd_ = ctx.fwd_dns_update_;
 
 2300        lease->fqdn_rev_ = ctx.rev_dns_update_;
 
 2302    if ((!ctx.hwaddr_ && lease->hwaddr_) ||
 
 2304         (!lease->hwaddr_ || (*ctx.hwaddr_ != *lease->hwaddr_)))) {
 
 2306        lease->hwaddr_ = ctx.hwaddr_;
 
 2314        .arg(ctx.query_->getLabel())
 
 2315        .arg(lease->toText());
 
 2319    int hook_point = ctx.query_->getType() == 
DHCPV6_RENEW ?
 
 2320        Hooks.hook_index_lease6_renew_ : 
Hooks.hook_index_lease6_rebind_;
 
 2328        ScopedCalloutHandleState callout_handle_state(callout_handle);
 
 2331        ScopedEnableOptionsCopy<Pkt6> query6_options_copy(ctx.query_);
 
 2334        callout_handle->setArgument(
"query6", ctx.query_);
 
 2337        callout_handle->setArgument(
"lease6", lease);
 
 2341            callout_handle->setArgument(
"ia_na", ctx.currentIA().ia_rsp_);
 
 2343            callout_handle->setArgument(
"ia_pd", ctx.currentIA().ia_rsp_);
 
 2356                .arg(ctx.query_->getName());
 
 2363        bool update_stats = 
false;
 
 2367        if (old_data->expired()) {
 
 2368            reclaimExpiredLease(old_data, ctx.callout_handle_);
 
 2372            if (ctx.subnet_->inPool(ctx.currentIA().type_, old_data->addr_)) {
 
 2373                update_stats = 
true;
 
 2386            setLeaseReusable(lease, current_preferred_lft, ctx);
 
 2391        if (lease->reuseable_valid_lft_ == 0) {
 
 2392            auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, 
false);
 
 2394                lease->pool_id_ = pool->getID();
 
 2400           old_data->reuseable_valid_lft_ = lease->reuseable_valid_lft_;
 
 2407                                       "assigned-nas" : 
"assigned-pds"),
 
 2408                static_cast<int64_t
>(1));
 
 2413                                       "cumulative-assigned-nas" : 
"cumulative-assigned-pds"),
 
 2414                static_cast<int64_t
>(1));
 
 2416            auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, 
false);
 
 2421                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 2423                                                                  "assigned-nas" : 
"assigned-pds")),
 
 2424                    static_cast<int64_t
>(1));
 
 2429                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 2431                                                                  "cumulative-assigned-nas" : 
"cumulative-assigned-pds")),
 
 2432                    static_cast<int64_t
>(1));
 
 2436                                          "cumulative-assigned-nas" : 
"cumulative-assigned-pds",
 
 2437                                          static_cast<int64_t
>(1));
 
 2450    ctx.currentIA().changed_leases_.push_back(old_data);
 
 2456    for (
auto const& lease_it : leases) {
 
 2458        if (ctx.currentIA().isNewResource(lease->addr_, lease->prefixlen_)) {
 
 2460            updated_leases.push_back(lease);
 
 2464        lease->reuseable_valid_lft_ = 0;
 
 2465        lease->fqdn_fwd_ = ctx.fwd_dns_update_;
 
 2466        lease->fqdn_rev_ = ctx.rev_dns_update_;
 
 2467        lease->hostname_ = ctx.hostname_;
 
 2468        uint32_t current_preferred_lft = lease->preferred_lft_;
 
 2469        if (lease->valid_lft_ == 0) {
 
 2471            getLifetimes6(ctx, lease->preferred_lft_, lease->valid_lft_);
 
 2473        if (!ctx.fake_allocation_) {
 
 2474            bool update_stats = 
false;
 
 2482                if (inAllowedPool(ctx, ctx.currentIA().type_,
 
 2483                                  lease->addr_, 
true)) {
 
 2484                    update_stats = 
true;
 
 2489                                 !(lease->hasIdenticalFqdn(*lease_it)));
 
 2491            lease->cltt_ = time(NULL);
 
 2492            if (!fqdn_changed) {
 
 2493                setLeaseReusable(lease, current_preferred_lft, ctx);
 
 2496            if (lease->reuseable_valid_lft_ == 0) {
 
 2497                ctx.currentIA().changed_leases_.push_back(lease_it);
 
 2501                ctx.currentIA().reused_leases_.push_back(lease_it);
 
 2508                                           "assigned-nas" : 
"assigned-pds"),
 
 2509                    static_cast<int64_t
>(1));
 
 2514                                           "cumulative-assigned-nas" : 
"cumulative-assigned-pds"),
 
 2515                    static_cast<int64_t
>(1));
 
 2517                auto const& pool = ctx.subnet_->getPool(ctx.currentIA().type_, lease->addr_, 
false);
 
 2522                                                                      "pool" : 
"pd-pool", pool->getID(),
 
 2524                                                                      "assigned-nas" : 
"assigned-pds")),
 
 2525                        static_cast<int64_t
>(1));
 
 2530                                                                      "pool" : 
"pd-pool", pool->getID(),
 
 2532                                                                      "cumulative-assigned-nas" : 
"cumulative-assigned-pds")),
 
 2533                        static_cast<int64_t
>(1));
 
 2537                                              "cumulative-assigned-nas" : 
"cumulative-assigned-pds",
 
 2538                                              static_cast<int64_t
>(1));
 
 2542        updated_leases.push_back(lease);
 
 2545    return (updated_leases);
 
 2550                                   const uint16_t timeout,
 
 2551                                   const bool remove_lease,
 
 2552                                   const uint16_t max_unwarned_cycles) {
 
 2561                                      max_unwarned_cycles);
 
 2562    } 
catch (
const std::exception& ex) {
 
 
 2571                                           const uint16_t timeout,
 
 2572                                           const bool remove_lease,
 
 2573                                           const uint16_t max_unwarned_cycles) {
 
 2583    bool incomplete_reclamation = 
false;
 
 2586    if (max_leases > 0) {
 
 2595        if (leases.size() > max_leases) {
 
 2597            incomplete_reclamation = 
true;
 
 2610    if (!leases.empty() &&
 
 2615    size_t leases_processed = 0;
 
 2616    for (
auto const& lease : leases) {
 
 2624                reclaimExpiredLease(lease, remove_lease, callout_handle);
 
 2627                reclaimExpiredLease(lease, remove_lease, callout_handle);
 
 2631        } 
catch (
const std::exception& ex) {
 
 2633                .arg(lease->addr_.toText())
 
 2644            if (!incomplete_reclamation) {
 
 2645                if (leases_processed < leases.size()) {
 
 2646                    incomplete_reclamation = 
true;
 
 2663        .arg(leases_processed)
 
 2668    if (incomplete_reclamation) {
 
 2669        ++incomplete_v6_reclamations_;
 
 2672        if ((max_unwarned_cycles > 0) &&
 
 2673            (incomplete_v6_reclamations_ > max_unwarned_cycles)) {
 
 2675                .arg(max_unwarned_cycles);
 
 2677            incomplete_v6_reclamations_ = 0;
 
 2682        incomplete_v6_reclamations_ = 0;
 
 
 2695    uint64_t deleted_leases = 0;
 
 2701    } 
catch (
const std::exception& ex) {
 
 2708        .arg(deleted_leases);
 
 
 2713                                   const uint16_t timeout,
 
 2714                                   const bool remove_lease,
 
 2715                                   const uint16_t max_unwarned_cycles) {
 
 2724                                      max_unwarned_cycles);
 
 2725    } 
catch (
const std::exception& ex) {
 
 
 2734                                           const uint16_t timeout,
 
 2735                                           const bool remove_lease,
 
 2736                                           const uint16_t max_unwarned_cycles) {
 
 2746    bool incomplete_reclamation = 
false;
 
 2749    if (max_leases > 0) {
 
 2758        if (leases.size() > max_leases) {
 
 2760            incomplete_reclamation = 
true;
 
 2773    if (!leases.empty() &&
 
 2778    size_t leases_processed = 0;
 
 2779    for (
auto const& lease : leases) {
 
 2787                reclaimExpiredLease(lease, remove_lease, callout_handle);
 
 2790                reclaimExpiredLease(lease, remove_lease, callout_handle);
 
 2794        } 
catch (
const std::exception& ex) {
 
 2796                .arg(lease->addr_.toText())
 
 2807            if (!incomplete_reclamation) {
 
 2808                if (leases_processed < leases.size()) {
 
 2809                    incomplete_reclamation = 
true;
 
 2826        .arg(leases_processed)
 
 2831    if (incomplete_reclamation) {
 
 2832        ++incomplete_v4_reclamations_;
 
 2835        if ((max_unwarned_cycles > 0) &&
 
 2836            (incomplete_v4_reclamations_ > max_unwarned_cycles)) {
 
 2838                .arg(max_unwarned_cycles);
 
 2840            incomplete_v4_reclamations_ = 0;
 
 2845        incomplete_v4_reclamations_ = 0;
 
 
 2852template<
typename LeasePtrType>
 
 2854AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease, 
const bool remove_lease,
 
 2856    reclaimExpiredLease(lease, remove_lease ? DB_RECLAIM_REMOVE : DB_RECLAIM_UPDATE,
 
 2860template<
typename LeasePtrType>
 
 2862AllocEngine::reclaimExpiredLease(
const LeasePtrType& lease,
 
 2867    if (!lease->stateExpiredReclaimed()) {
 
 2868        reclaimExpiredLease(lease, DB_RECLAIM_LEAVE_UNCHANGED, callout_handle);
 
 2873AllocEngine::reclaimExpiredLease(
const Lease6Ptr& lease,
 
 2874                                 const DbReclaimMode& reclaim_mode,
 
 2880        .arg(lease->addr_.toText())
 
 2881        .arg(
static_cast<int>(lease->prefixlen_));
 
 2887    bool skipped = 
false;
 
 2889    if (callout_handle) {
 
 2895        ScopedCalloutHandleState callout_handle_state(callout_handle);
 
 2897        callout_handle->deleteAllArguments();
 
 2898        callout_handle->setArgument(
"lease6", lease);
 
 2899        callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
 
 2919        bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
 
 2929            remove_lease = reclaimDeclined(lease);
 
 2931            if (reclaim_mode == DB_RECLAIM_LEAVE_UNCHANGED) {
 
 2932                isc_throw(Unexpected, 
"attempt to reuse a registered lease");
 
 2935            remove_lease = 
true;
 
 2938        if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
 
 2942            reclaimLeaseInDatabase<Lease6Ptr>(lease, remove_lease,
 
 2944                                                        &lease_mgr, ph::_1));
 
 2956                                                         "reclaimed-leases"),
 
 2957        static_cast<int64_t
>(1));
 
 2963            auto const& pool = subnet->getPool(lease->type_, lease->addr_, 
false);
 
 2969                                                                  pool->getID(), 
"reclaimed-leases")),
 
 2970                    static_cast<int64_t
>(1));
 
 2986                                      static_cast<int64_t
>(-1));
 
 2991                                                             "assigned-nas" : 
"assigned-pds"),
 
 2992                                      static_cast<int64_t
>(-1));
 
 2995            auto const& pool = subnet->getPool(lease->type_, lease->addr_, 
false);
 
 3000                                                                  "pool" : 
"pd-pool", pool->getID(),
 
 3002                                                                  "assigned-nas" : 
"assigned-pds")),
 
 3003                    static_cast<int64_t
>(-1));
 
 3010AllocEngine::reclaimExpiredLease(
const Lease4Ptr& lease,
 
 3011                                 const DbReclaimMode& reclaim_mode,
 
 3017        .arg(lease->addr_.toText());
 
 3023    bool skipped = 
false;
 
 3025    if (callout_handle) {
 
 3031        ScopedCalloutHandleState callout_handle_state(callout_handle);
 
 3033        callout_handle->setArgument(
"lease4", lease);
 
 3034        callout_handle->setArgument(
"remove_lease", reclaim_mode == DB_RECLAIM_REMOVE);
 
 3052        lease->hostname_.clear();
 
 3053        lease->fqdn_fwd_ = 
false;
 
 3054        lease->fqdn_rev_ = 
false;
 
 3058        bool remove_lease = (reclaim_mode == DB_RECLAIM_REMOVE);
 
 3068            remove_lease = reclaimDeclined(lease);
 
 3071        if (reclaim_mode != DB_RECLAIM_LEAVE_UNCHANGED) {
 
 3075            reclaimLeaseInDatabase<Lease4Ptr>(lease, remove_lease,
 
 3077                                                        &lease_mgr, ph::_1));
 
 3089                                                         "reclaimed-leases"),
 
 3090        static_cast<int64_t
>(1));
 
 3095        auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_, 
false);
 
 3100                                                              "reclaimed-leases")),
 
 3101                static_cast<int64_t
>(1));
 
 3113                                                         "assigned-addresses"),
 
 3114        static_cast<int64_t
>(-1));
 
 3117        auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_, 
false);
 
 3122                                                              "assigned-addresses")),
 
 3123                static_cast<int64_t
>(-1));
 
 3134    uint64_t deleted_leases = 0;
 
 3140    } 
catch (
const std::exception& ex) {
 
 3147        .arg(deleted_leases);
 
 
 3151AllocEngine::reclaimDeclined(
const Lease4Ptr& lease) {
 
 3166        callout_handle->setArgument(
"lease4", lease);
 
 3176                .arg(lease->addr_.toText());
 
 3182        .arg(lease->addr_.toText())
 
 3183        .arg(lease->valid_lft_);
 
 3189                                              "declined-addresses"),
 
 3190        static_cast<int64_t
>(-1));
 
 3193                                              "reclaimed-declined-addresses"),
 
 3194        static_cast<int64_t
>(1));
 
 3198        auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_, 
false);
 
 3202                                                                             "declined-addresses")),
 
 3203                static_cast<int64_t
>(-1));
 
 3207                                                                             "reclaimed-declined-addresses")),
 
 3208                static_cast<int64_t
>(1));
 
 3213    stats_mgr.
addValue(
"declined-addresses", 
static_cast<int64_t
>(-1));
 
 3215    stats_mgr.
addValue(
"reclaimed-declined-addresses", 
static_cast<int64_t
>(1));
 
 3223AllocEngine::reclaimDeclined(
const Lease6Ptr& lease) {
 
 3235        ScopedCalloutHandleState callout_handle_state(callout_handle);
 
 3238        callout_handle->setArgument(
"lease6", lease);
 
 3248                .arg(lease->addr_.toText());
 
 3254        .arg(lease->addr_.toText())
 
 3255        .arg(lease->valid_lft_);
 
 3261                                              "declined-addresses"),
 
 3262        static_cast<int64_t
>(-1));
 
 3265                                              "reclaimed-declined-addresses"),
 
 3266        static_cast<int64_t
>(1));
 
 3270        auto const& pool = subnet->getPool(lease->type_, lease->addr_, 
false);
 
 3274                                                                             "declined-addresses")),
 
 3275                static_cast<int64_t
>(-1));
 
 3279                                                                             "reclaimed-declined-addresses")),
 
 3280                static_cast<int64_t
>(1));
 
 3285    stats_mgr.
addValue(
"declined-addresses", 
static_cast<int64_t
>(-1));
 
 3287    stats_mgr.
addValue(
"reclaimed-declined-addresses", 
static_cast<int64_t
>(1));
 
 3297    lease->relay_id_.clear();
 
 3298    lease->remote_id_.clear();
 
 3299    if (lease->getContext()) {
 
 
 3306    if (lease->getContext()) {
 
 
 3312template<
typename LeasePtrType>
 
 3313void AllocEngine::reclaimLeaseInDatabase(
const LeasePtrType& lease,
 
 3314                                         const bool remove_lease,
 
 3315                                         const std::function<
void (
const LeasePtrType&)>&
 
 3316                                         lease_update_fun)
 const {
 
 3324    } 
else if (lease_update_fun) {
 
 3327        lease->reuseable_valid_lft_ = 0;
 
 3328        lease->hostname_.clear();
 
 3329        lease->fqdn_fwd_ = 
false;
 
 3330        lease->fqdn_rev_ = 
false;
 
 3333        lease_update_fun(lease);
 
 3342        .arg(lease->addr_.toText());
 
 3348        return(
"<empty subnet>");
 
 3352    subnet->getSharedNetwork(network);
 
 3353    std::ostringstream ss;
 
 3355        ss << 
"shared-network: " << network->getName();
 
 3357        ss << 
"subnet id: " << subnet->getID();
 
 
 3396        (!ctx.
subnet_->getReservationsOutOfPool() ||
 
 3407        if (
CfgMgr::instance().getCurrentCfg()->getCfgDbAccess()->getIPReservationsUnique()) {
 
 3412                    hosts.push_back(host);
 
 3426        for (
auto const& host : hosts) {
 
 3430                if (id_pair.first == host->getIdentifierType() &&
 
 3431                    id_pair.second == host->getIdentifier()) {
 
 3439        return (!hosts.empty());
 
 3461    if (ctx.
hosts_.empty()) {
 
 3466    auto global_host = ctx.
hosts_.find(SUBNET_ID_GLOBAL);
 
 3467    auto global_host_address = ((global_host != ctx.
hosts_.end() && global_host->second) ?
 
 3468                                 global_host->second->getIPv4Reservation() :
 
 3477        if (subnet->getReservationsGlobal() &&
 
 3479            (subnet->inRange(global_host_address))) {
 
 3484        if (subnet->getReservationsInSubnet()) {
 
 3485            auto host = ctx.
hosts_.find(subnet->getID());
 
 3490            if (host != ctx.
hosts_.end() && host->second) {
 
 3491                auto reservation = host->second->getIPv4Reservation();
 
 3492                if (!reservation.isV4Zero() &&
 
 3493                    (!subnet->getReservationsOutOfPool() ||
 
 3503        subnet = subnet->getNextSubnet(ctx.
subnet_, ctx.
query_->getClasses());
 
 3509            .arg(ctx.
query_->getLabel())
 
 3510            .arg(global_host_address.toText())
 
 3537    auto const& classes = ctx.
query_->getClasses();
 
 3541    bool try_clientid_lookup = (ctx.
clientid_ &&
 
 3545    if (try_clientid_lookup) {
 
 3554             subnet = subnet->getNextSubnet(original_subnet, classes)) {
 
 3559            if (subnet->getMatchClientId()) {
 
 3560                for (
auto const& l : leases_client_id) {
 
 3561                    if (l->subnet_id_ == subnet->getID()) {
 
 3574    if (!client_lease && ctx.
hwaddr_) {
 
 3580             subnet = subnet->getNextSubnet(original_subnet, classes)) {
 
 3582            if (subnet->getMatchClientId()) {
 
 3588            for (
auto const& client_lease_it : leases_hw_address) {
 
 3589                Lease4Ptr existing_lease = client_lease_it;
 
 3590                if ((existing_lease->subnet_id_ == subnet->getID()) &&
 
 3591                    existing_lease->belongsToClient(ctx.
hwaddr_, client_id)) {
 
 3593                    client_lease = existing_lease;
 
 3621    auto const& classes = ctx.
query_->getClasses();
 
 3623    while (current_subnet) {
 
 3632        current_subnet = current_subnet->getNextSubnet(ctx.
subnet_, classes);
 
 3659                                            const bool fwd_dns_update,
 
 3660                                            const bool rev_dns_update,
 
 3661                                            const std::string& hostname,
 
 3662                                            const bool fake_allocation,
 
 3663                                            const uint32_t offer_lft)
 
 
 3683        if (host != 
hosts_.cend()) {
 
 3684            return (host->second);
 
 
 3694        auto host = 
hosts_.find(SUBNET_ID_GLOBAL);
 
 3695        if (host != 
hosts_.cend()) {
 
 3696            return (host->second);
 
 
 3706    if (ddns_params_ && 
subnet_ && (
subnet_->getID() == ddns_params_->getSubnetId())) {
 
 3707        return (ddns_params_);
 
 3713        return (ddns_params_);
 
 
 3735    auto const& classes = ctx.
query_->getClasses();
 
 3736    if (subnet && !subnet->clientSupported(classes)) {
 
 3737        ctx.
subnet_ = subnet->getNextSubnet(subnet, classes);
 
 3761            .arg(ctx.
query_->getLabel())
 
 
 3779        !subnet->getReservationsInSubnet()) {
 
 3785        subnet->getReservationsGlobal()) {
 
 3788            ctx.
hosts_[SUBNET_ID_GLOBAL] = ghost;
 
 3791            if (!subnet->getReservationsInSubnet()) {
 
 3797    std::map<SubnetID, ConstHostPtr> host_map;
 
 3799    subnet->getSharedNetwork(network);
 
 3808    const bool use_single_query = network &&
 
 3812    if (use_single_query) {
 
 3816                                                                   id_pair.second.size());
 
 3820            for (
auto const& host : hosts) {
 
 3821                if (host->getIPv4SubnetID() != SUBNET_ID_GLOBAL) {
 
 3822                    host_map[host->getIPv4SubnetID()] = host;
 
 3828    auto const& classes = ctx.
query_->getClasses();
 
 3834        if (subnet->clientSupported(classes) && subnet->getReservationsInSubnet()) {
 
 3837            if (use_single_query) {
 
 3838                if (host_map.count(subnet->getID()) > 0) {
 
 3839                    ctx.
hosts_[subnet->getID()] = host_map[subnet->getID()];
 
 3847                                                                 id_pair.second.size());
 
 3850                        ctx.
hosts_[subnet->getID()] = host;
 
 3860        subnet = subnet->getNextSubnet(ctx.
subnet_, classes);
 
 3866    for (
auto const& host : ctx.
hosts_) {
 
 3867        host.second->encapsulateOptions();
 
 
 3877                                        &id_pair.second[0], id_pair.second.size());
 
 
 3894    findClientLease(ctx, client_lease);
 
 3907    if (hasAddressReservation(ctx)) {
 
 3911            .arg(ctx.
query_->getLabel())
 
 3912            .arg(ctx.
currentHost()->getIPv4Reservation().toText());
 
 3918        if (!client_lease || (client_lease->addr_ != ctx.
currentHost()->getIPv4Reservation())) {
 
 3925            new_lease = allocateOrReuseLease4(ctx.
currentHost()->getIPv4Reservation(), ctx,
 
 3929                    .arg(ctx.
query_->getLabel())
 
 3930                    .arg(ctx.
currentHost()->getIPv4Reservation().toText())
 
 3935                                                  "v4-reservation-conflicts"),
 
 3936                                              static_cast<int64_t
>(1));
 
 3938                                              static_cast<int64_t
>(1));
 
 3942            new_lease = renewLease4(client_lease, ctx);
 
 3955    if (!new_lease && client_lease && inAllowedPool(ctx, client_lease->addr_) &&
 
 3956        !addressReserved(client_lease->addr_, ctx)) {
 
 3960            .arg(ctx.
query_->getLabel());
 
 3966            (time(NULL) + ctx.
offer_lft_ < client_lease->getExpirationTime())) {
 
 3970        new_lease = renewLease4(client_lease, ctx);
 
 3987            .arg(ctx.
query_->getLabel());
 
 4000            .arg(ctx.
query_->getLabel());
 
 4002        new_lease = allocateUnreservedLease4(ctx);
 
 4021                                                             "assigned-addresses"),
 
 4022                                      static_cast<int64_t
>(-1));
 
 4025                             ->getBySubnetId(lease->subnet_id_);
 
 4027            auto const& pool = subnet->getPool(
Lease::TYPE_V4, lease->addr_, 
false);
 
 4031                                                                      "assigned-addresses")),
 
 4032                                              static_cast<int64_t
>(-1));
 
 
 4044    findClientLease(ctx, client_lease);
 
 4060                .arg(ctx.
query_->getLabel())
 
 4066    } 
else if (hasAddressReservation(ctx)) {
 
 4075            .arg(ctx.
query_->getLabel())
 
 4087        if (existing && !existing->expired() &&
 
 4088            !existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
 
 4093                .arg(ctx.
query_->getLabel())
 
 4103        if (hasAddressReservation(ctx) &&
 
 4111            if (!existing || existing->expired()) {
 
 4115                    .arg(ctx.
query_->getLabel())
 
 4116                    .arg(ctx.
currentHost()->getIPv4Reservation().toText())
 
 4126        if ((!hasAddressReservation(ctx) ||
 
 4132                .arg(ctx.
query_->getLabel())
 
 4144        if (((client_lease && existing) && (client_lease->addr_ != existing->addr_) &&
 
 4146             (existing->belongsToClient(ctx.
hwaddr_, ctx.
subnet_->getMatchClientId() ?
 
 4149            auto conflicted_lease = client_lease;
 
 4150            client_lease = existing;
 
 4167            ((hasAddressReservation(ctx) &&
 
 4169             inAllowedPool(ctx, client_lease->addr_))) {
 
 4173                .arg(ctx.
query_->getLabel())
 
 4175            return (renewLease4(client_lease, ctx));
 
 4189            .arg(ctx.
query_->getLabel())
 
 4204            .arg(ctx.
query_->getLabel());
 
 4209        new_lease = allocateUnreservedLease4(ctx);
 
 4215    if (new_lease && client_lease) {
 
 4220            .arg(ctx.
query_->getLabel())
 
 4221            .arg(client_lease->addr_.toText());
 
 4242    if (!classes.
empty()) {
 
 4248        for (
auto const& name : classes) {
 
 4250            if (cl && (!cl->getOfferLft().unspecified())) {
 
 4251                offer_lft = cl->getOfferLft();
 
 4259        offer_lft = ctx.
subnet_->getOfferLft();
 
 
 4268    if (ctx.
query_->inClass(
"BOOTP")) {
 
 4273    uint32_t requested_lft = 0;
 
 4276        OptionUint32Ptr opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
 
 4278            requested_lft = opt_lft->getValue();
 
 4286    if (!classes.
empty()) {
 
 4292        for (
auto const& name : classes) {
 
 4294            if (cl && (!cl->getValid().unspecified())) {
 
 4295                candidate_lft = cl->getValid();
 
 4302    if (!candidate_lft) {
 
 4303        candidate_lft = ctx.
subnet_->getValid();
 
 4308    if (requested_lft > 0) {
 
 4309        return (candidate_lft.
get(requested_lft));
 
 4313    return (candidate_lft.
get());
 
 
 4317AllocEngine::createLease4(
const ClientContext4& ctx, 
const IOAddress& addr,
 
 4327    uint32_t valid_lft = (ctx.offer_lft_ ? ctx.offer_lft_ : 
getValidLft(ctx));
 
 4329    time_t now = time(NULL);
 
 4332    if (ctx.subnet_->getMatchClientId()) {
 
 4333        client_id = ctx.clientid_;
 
 4336    Lease4Ptr lease(
new Lease4(addr, ctx.hwaddr_, client_id,
 
 4337                               valid_lft, now, ctx.subnet_->getID()));
 
 4340    lease->fqdn_fwd_ = ctx.fwd_dns_update_;
 
 4341    lease->fqdn_rev_ = ctx.rev_dns_update_;
 
 4342    lease->hostname_ = ctx.hostname_;
 
 4348    if (ctx.callout_handle_ &&
 
 4355        ScopedCalloutHandleState callout_handle_state(ctx.callout_handle_);
 
 4358        ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.query_);
 
 4362        ctx.callout_handle_->setArgument(
"query4", ctx.query_);
 
 4369            boost::dynamic_pointer_cast<const Subnet4>(ctx.subnet_);
 
 4370        ctx.callout_handle_->setArgument(
"subnet4", subnet4);
 
 4373        ctx.callout_handle_->setArgument(
"fake_allocation", ctx.fake_allocation_);
 
 4376        ctx.callout_handle_->setArgument(
"offer_lft", ctx.offer_lft_);
 
 4379        ctx.callout_handle_->setArgument(
"lease4", lease);
 
 4384        callout_status = ctx.callout_handle_->getStatus();
 
 4396        ctx.callout_handle_->getArgument(
"lease4", lease);
 
 4399    if (ctx.fake_allocation_ && ctx.offer_lft_) {
 
 4403        lease->fqdn_fwd_ = 
false;
 
 4404        lease->fqdn_rev_ = 
false;
 
 4407    if (!ctx.fake_allocation_ || ctx.offer_lft_) {
 
 4408        auto const& pool = ctx.subnet_->getPool(
Lease::TYPE_V4, lease->addr_, 
false);
 
 4410            lease->pool_id_ = pool->getID();
 
 4419                                       "assigned-addresses"),
 
 4420                static_cast<int64_t
>(1));
 
 4424                                       "cumulative-assigned-addresses"),
 
 4425                static_cast<int64_t
>(1));
 
 4431                                                                 "assigned-addresses")),
 
 4432                    static_cast<int64_t
>(1));
 
 4437                                                                 "cumulative-assigned-addresses")),
 
 4438                    static_cast<int64_t
>(1));
 
 4442                                          static_cast<int64_t
>(1));
 
 4461AllocEngine::renewLease4(
const Lease4Ptr& lease,
 
 4462                         AllocEngine::ClientContext4& ctx) {
 
 4464        isc_throw(BadValue, 
"null lease specified for renewLease4");
 
 4471    Lease4Ptr old_values = boost::make_shared<Lease4>(*lease);
 
 4472    ctx.
old_lease_.reset(
new Lease4(*old_values));
 
 4476    lease->reuseable_valid_lft_ = 0;
 
 4477    if (!updateLease4Information(lease, ctx)) {
 
 4478        setLeaseReusable(lease, ctx);
 
 4503        ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
 
 4510            boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
 
 4519        ctx.
callout_handle_->setArgument(
"clientid", subnet4->getMatchClientId() ?
 
 4545            lease->pool_id_ = pool->getID();
 
 4555                                       "assigned-addresses"),
 
 4556                static_cast<int64_t
>(1));
 
 4560                                       "cumulative-assigned-addresses"),
 
 4561                static_cast<int64_t
>(1));
 
 4567                                                                  "assigned-addresses")),
 
 4568                    static_cast<int64_t
>(1));
 
 4573                                                                  "cumulative-assigned-addresses")),
 
 4574                    static_cast<int64_t
>(1));
 
 4578                                          static_cast<int64_t
>(1));
 
 4584        *lease = *old_values;
 
 4591AllocEngine::reuseExpiredLease4(
Lease4Ptr& expired,
 
 4592                                AllocEngine::ClientContext4& ctx,
 
 4595        isc_throw(BadValue, 
"null lease specified for reuseExpiredLease");
 
 4599        isc_throw(BadValue, 
"null subnet specified for the reuseExpiredLease");
 
 4610    expired->reuseable_valid_lft_ = 0;
 
 4611    static_cast<void>(updateLease4Information(expired, ctx));
 
 4615        .arg(ctx.
query_->getLabel())
 
 4616        .arg(expired->toText());
 
 4623        ScopedEnableOptionsCopy<Pkt4> query4_options_copy(ctx.
query_);
 
 4640            boost::dynamic_pointer_cast<const Subnet4>(ctx.
subnet_);
 
 4674            expired->pool_id_ = pool->getID();
 
 4682                                   "assigned-addresses"),
 
 4683            static_cast<int64_t
>(1));
 
 4687                                   "cumulative-assigned-addresses"),
 
 4688            static_cast<int64_t
>(1));
 
 4694                                                              "assigned-addresses")),
 
 4695                static_cast<int64_t
>(1));
 
 4700                                                              "cumulative-assigned-addresses")),
 
 4701                static_cast<int64_t
>(1));
 
 4705                                      static_cast<int64_t
>(1));
 
 4717AllocEngine::allocateOrReuseLease4(
const IOAddress& candidate, 
ClientContext4& ctx,
 
 4719    ctx.conflicting_lease_.reset();
 
 4723        if (exist_lease->expired()) {
 
 4724            ctx.old_lease_ = 
Lease4Ptr(
new Lease4(*exist_lease));
 
 4728            ctx.old_lease_->hostname_.clear();
 
 4729            ctx.old_lease_->fqdn_fwd_ = 
false;
 
 4730            ctx.old_lease_->fqdn_rev_ = 
false;
 
 4731            return (reuseExpiredLease4(exist_lease, ctx, callout_status));
 
 4737            ctx.conflicting_lease_ = exist_lease;
 
 4741        return (createLease4(ctx, candidate, callout_status));
 
 4761    ctx.subnet_->getSharedNetwork(network);
 
 4768        ctx.subnet_ = subnet = network->getPreferredSubnet(ctx.subnet_);
 
 4782    uint64_t subnets_with_unavail_leases = 0;
 
 4785    uint64_t subnets_with_unavail_pools = 0;
 
 4787    auto const& classes = ctx.query_->getClasses();
 
 4791        if (subnet->getMatchClientId()) {
 
 4792            client_id = ctx.clientid_;
 
 4804            (attempts_ == 0 || possible_attempts < attempts_) ?
 
 4808        if (max_attempts > 0) {
 
 4811            ++subnets_with_unavail_leases;
 
 4815            ++subnets_with_unavail_pools;
 
 4818        bool exclude_first_last_24 = ((subnet->get().second <= 24) &&
 
 4823        for (
uint128_t i = 0; i < max_attempts; ++i) {
 
 4828            IOAddress candidate = allocator->pickAddress(classes,
 
 4830                                                         ctx.requested_address_);
 
 4837            if (exclude_first_last_24) {
 
 4839                auto const& bytes = candidate.
toBytes();
 
 4840                if ((bytes.size() != 4) ||
 
 4841                    (bytes[3] == 0) || (bytes[3] == 255U)) {
 
 4848            if (check_reservation_first && addressReserved(candidate, ctx)) {
 
 4855            ResourceHandler4 resource_handler;
 
 4857                !resource_handler.
tryLock4(candidate)) {
 
 4866                if (check_reservation_first || !addressReserved(candidate, ctx)) {
 
 4868                    new_lease = createLease4(ctx, candidate, callout_status);
 
 4872                if (exist_lease->expired() &&
 
 4873                    (check_reservation_first || !addressReserved(candidate, ctx))) {
 
 4874                    ctx.old_lease_ = 
Lease4Ptr(
new Lease4(*exist_lease));
 
 4875                    new_lease = reuseExpiredLease4(exist_lease, ctx, callout_status);
 
 4893            subnet = subnet->getNextSubnet(original_subnet, classes);
 
 4896                ctx.subnet_ = subnet;
 
 4905            .arg(ctx.query_->getLabel())
 
 4906            .arg(network->getName())
 
 4907            .arg(subnets_with_unavail_leases)
 
 4908            .arg(subnets_with_unavail_pools);
 
 4910                                      static_cast<int64_t
>(1));
 
 4913                                   "v4-allocation-fail-shared-network"),
 
 4914                                   static_cast<int64_t
>(1));
 
 4918        std::string shared_network = ctx.subnet_->getSharedNetworkName();
 
 4919        if (shared_network.empty()) {
 
 4920            shared_network = 
"(none)";
 
 4923            .arg(ctx.query_->getLabel())
 
 4924            .arg(ctx.subnet_->toText())
 
 4925            .arg(ctx.subnet_->getID())
 
 4926            .arg(shared_network);
 
 4928                                      static_cast<int64_t
>(1));
 
 4931                                   "v4-allocation-fail-subnet"),
 
 4932                                   static_cast<int64_t
>(1));
 
 4934    if (total_attempts == 0) {
 
 4940            .arg(ctx.query_->getLabel());
 
 4942                                      static_cast<int64_t
>(1));
 
 4945                                   "v4-allocation-fail-no-pools"),
 
 4946                                   static_cast<int64_t
>(1));
 
 4953            .arg(ctx.query_->getLabel())
 
 4954            .arg(total_attempts);
 
 4956                                      static_cast<int64_t
>(1));
 
 4959                                   "v4-allocation-fail"),
 
 4960                                   static_cast<int64_t
>(1));
 
 4963    if (!classes.empty()) {
 
 4965            .arg(ctx.query_->getLabel())
 
 4966            .arg(classes.toText());
 
 4968                                      static_cast<int64_t
>(1));
 
 4971                                   "v4-allocation-fail-classes"),
 
 4972                                   static_cast<int64_t
>(1));
 
 4979AllocEngine::updateLease4Information(
const Lease4Ptr& lease,
 
 4980                                     AllocEngine::ClientContext4& ctx)
 const {
 
 4981    bool changed = 
false;
 
 4982    if (lease->subnet_id_ != ctx.
subnet_->getID()) {
 
 4984        lease->subnet_id_ = ctx.
subnet_->getID();
 
 4986    if ((!ctx.
hwaddr_ && lease->hwaddr_) ||
 
 4988         (!lease->hwaddr_ || (*ctx.
hwaddr_ != *lease->hwaddr_)))) {
 
 4993        if (!lease->client_id_ || (*ctx.
clientid_ != *lease->client_id_)) {
 
 4997    } 
else if (lease->client_id_) {
 
 5001    lease->cltt_ = time(NULL);
 
 5007    if (lease->valid_lft_ != lease->current_valid_lft_) {
 
 5031    bool changed = 
false;
 
 5034    if (!ctx.
subnet_->getStoreExtendedInfo()) {
 
 5049        sao->boolValue() && ctx.
query_->inClass(
"STASH_AGENT_OPTIONS")) {
 
 5058    extended_info->set(
"sub-options", relay_agent);
 
 5062        std::vector<uint8_t> bytes = remote_id->toBinary();
 
 5063        lease->remote_id_ = bytes;
 
 5064        if (bytes.size() > 0) {
 
 5065            extended_info->set(
"remote-id",
 
 5072        std::vector<uint8_t> bytes = relay_id->toBinary(
false);
 
 5073        lease->relay_id_ = bytes;
 
 5074        if (bytes.size() > 0) {
 
 5075            extended_info->set(
"relay-id",
 
 5081    return (lease->updateUserContextISC(
"relay-agent-info", extended_info));
 
 
 5091    if (!ctx.
subnet_->getStoreExtendedInfo()) {
 
 5096    if (ctx.
query_->relay_info_.empty()) {
 
 5111    for (
auto const& relay : ctx.
query_->relay_info_) {
 
 5120        if (!relay.options_.empty()) {
 
 5125                const uint8_t* cp = buf.
getData();
 
 5126                std::vector<uint8_t> bytes;
 
 5127                std::stringstream ss;
 
 5135            if (remote_id_it != relay.options_.end()) {
 
 5136                OptionPtr remote_id = remote_id_it->second;
 
 5138                    std::vector<uint8_t> bytes = remote_id->toBinary();
 
 5139                    if (bytes.size() > 0) {
 
 5140                        relay_elem->set(
"remote-id",
 
 5147            if (relay_id_it != relay.options_.end()) {
 
 5148                OptionPtr relay_id = relay_id_it->second;
 
 5150                    std::vector<uint8_t> bytes = relay_id->toBinary(
false);
 
 5151                    if (bytes.size() > 0) {
 
 5152                        relay_elem->set(
"relay-id",
 
 5159        extended_info->add(relay_elem);
 
 5163    if (lease->updateUserContextISC(
"relay-info", extended_info)) {
 
 
 5169AllocEngine::setLeaseReusable(
const Lease4Ptr& lease,
 
 5170                              const ClientContext4& ctx)
 const {
 
 5172    lease->reuseable_valid_lft_ = 0;
 
 5188    if (lease->cltt_ < lease->current_cltt_) {
 
 5192    uint32_t age = lease->cltt_ - lease->current_cltt_;
 
 5194    if (age >= lease->current_valid_lft_) {
 
 5199    uint32_t max_age = 0;
 
 5200    if (!subnet->getCacheMaxAge().unspecified()) {
 
 5201        max_age = subnet->getCacheMaxAge().get();
 
 5202        if ((max_age == 0) || (age > max_age)) {
 
 5208    if (!subnet->getCacheThreshold().unspecified()) {
 
 5209        double threshold = subnet->getCacheThreshold().get();
 
 5210        if ((threshold <= 0.) || (threshold > 1.)) {
 
 5213        max_age = lease->valid_lft_ * threshold;
 
 5214        if (age > max_age) {
 
 5225    lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
 
 5229AllocEngine::setLeaseReusable(
const Lease6Ptr& lease,
 
 5230                              uint32_t current_preferred_lft,
 
 5233    lease->reuseable_valid_lft_ = 0;
 
 5234    lease->reuseable_preferred_lft_ = 0;
 
 5244    if (lease->cltt_ < lease->current_cltt_) {
 
 5248    uint32_t age = lease->cltt_ - lease->current_cltt_;
 
 5250    if (age >= lease->current_valid_lft_) {
 
 5255    uint32_t max_age = 0;
 
 5256    if (!subnet->getCacheMaxAge().unspecified()) {
 
 5257        max_age = subnet->getCacheMaxAge().get();
 
 5258        if ((max_age == 0) || (age > max_age)) {
 
 5264    if (!subnet->getCacheThreshold().unspecified()) {
 
 5265        double threshold = subnet->getCacheThreshold().get();
 
 5266        if ((threshold <= 0.) || (threshold > 1.)) {
 
 5269        max_age = lease->valid_lft_ * threshold;
 
 5270        if (age > max_age) {
 
 5282        (current_preferred_lft == 0)) {
 
 5284        lease->reuseable_preferred_lft_ = current_preferred_lft;
 
 5285    } 
else if (current_preferred_lft > age) {
 
 5286        lease->reuseable_preferred_lft_ = current_preferred_lft - age;
 
 5294        lease->reuseable_valid_lft_ = lease->current_valid_lft_ - age;
 
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_SKIP
skip the next processing step
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
This is a base class for exceptions thrown from the DNS library module.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a function is called in a prohibited way.
The IOAddress class represents an IP addresses (version agnostic)
static const IOAddress & IPV4_ZERO_ADDRESS()
Returns an address set to all zeros.
bool isV4Zero() const
Convenience function to check if it is an IPv4 zero address.
std::string toText() const
Convert the address to a string.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
bool isV6Zero() const
Convenience function to check if it is an IPv4 zero address.
static const IOAddress & IPV6_ZERO_ADDRESS()
Returns an IPv6 zero address.
static ElementPtr create(const Position &pos=ZERO_POSITION())
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Notes: IntElement type is changed to int64_t.
Multiple lease records found where one expected.
static IPv6Resrv makeIPv6Resrv(const Lease6 &lease)
Creates an IPv6Resrv instance from a Lease6.
void updateLease6ExtendedInfo(const Lease6Ptr &lease, const ClientContext6 &ctx) const
Stores additional client query parameters on a V6 lease.
void reclaimExpiredLeases6Internal(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Body of reclaimExpiredLeases6.
bool updateLease4ExtendedInfo(const Lease4Ptr &lease, const ClientContext4 &ctx) const
Stores additional client query parameters on a V4 lease.
static ConstHostPtr findGlobalReservation(ClientContext6 &ctx)
Attempts to find the host reservation for the client.
AllocEngine(isc::util::uint128_t const &attempts)
Constructor.
std::pair< Host::IdentifierType, std::vector< uint8_t > > IdentifierPair
A tuple holding host identifier type and value.
void clearReclaimedExtendedInfo(const Lease4Ptr &lease) const
Clear extended info from a reclaimed V4 lease.
isc::util::ReadWriteMutex rw_mutex_
The read-write mutex.
static void getLifetimes6(ClientContext6 &ctx, uint32_t &preferred, uint32_t &valid)
Determines the preferred and valid v6 lease lifetimes.
static void findReservation(ClientContext6 &ctx)
static uint32_t getOfferLft(const ClientContext4 &ctx, bool only_on_discover=true)
Returns the offer lifetime based on the v4 context.
void reclaimExpiredLeases4Internal(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Body of reclaimExpiredLeases4.
void deleteExpiredReclaimedLeases4(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
static uint32_t getValidLft(const ClientContext4 &ctx)
Returns the valid lifetime based on the v4 context.
void reclaimExpiredLeases6(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Reclaims expired IPv6 leases.
static std::string labelNetworkOrSubnet(ConstSubnetPtr subnet)
Generates a label for subnet or shared-network from subnet.
void reclaimExpiredLeases4(const size_t max_leases, const uint16_t timeout, const bool remove_lease, const uint16_t max_unwarned_cycles=0)
Reclaims expired IPv4 leases.
Lease4Ptr allocateLease4(ClientContext4 &ctx)
Returns IPv4 lease.
void deleteExpiredReclaimedLeases6(const uint32_t secs)
Deletes reclaimed leases expired more than specified amount of time ago.
Lease6Collection allocateLeases6(ClientContext6 &ctx)
Allocates IPv6 leases for a given IA container.
Lease6Collection renewLeases6(ClientContext6 &ctx)
Renews existing DHCPv6 leases for a given IA.
PrefixLenMatchType
Type of preferred PD-pool prefix length selection criteria.
static bool isValidPrefixPool(Allocator::PrefixLenMatchType prefix_length_match, PoolPtr pool, uint8_t hint_prefix_length)
Check if the pool matches the selection criteria relative to the provided hint prefix length.
D2ClientMgr & getD2ClientMgr()
Fetches the DHCP-DDNS manager.
static CfgMgr & instance()
returns a single instance of Configuration Manager
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Container for storing client class names.
bool empty() const
Check if classes is empty.
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
ConstHostCollection getAll6(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv6 subnet.
ConstHostCollection getAll4(const SubnetID &subnet_id, const HostMgrOperationTarget target) const
Return all hosts in a DHCPv4 subnet.
ConstHostCollection getAll(const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Return all hosts connected to any subnet for which reservations have been made using a specified iden...
bool getDisableSingleQuery() const
Returns the disable single query flag.
static HostMgr & instance()
Returns a sole instance of the HostMgr.
ConstHostPtr get4(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv4 subnet.
ConstHostPtr get6(const SubnetID &subnet_id, const Host::IdentifierType &identifier_type, const uint8_t *identifier_begin, const size_t identifier_len, const HostMgrOperationTarget target) const
Returns a host connected to the IPv6 subnet.
IPv6 reservation for a host.
Type
Type of the reservation.
static TrackingLeaseMgr & instance()
Return current lease manager.
virtual Lease6Collection getLeases6(Lease::Type type, const DUID &duid, uint32_t iaid) const =0
Returns existing IPv6 leases for a given DUID+IA combination.
virtual void getExpiredLeases6(Lease6Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv6 leases.
virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv6 leases.
virtual Lease4Ptr getLease4(const isc::asiolink::IOAddress &addr) const =0
Returns an IPv4 lease for specified IPv4 address.
virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs)=0
Deletes all expired and reclaimed DHCPv4 leases.
virtual bool addLease(const Lease4Ptr &lease)=0
Adds an IPv4 lease.
virtual bool deleteLease(const Lease4Ptr &lease)=0
Deletes an IPv4 lease.
virtual void getExpiredLeases4(Lease4Collection &expired_leases, const size_t max_leases) const =0
Returns a collection of expired DHCPv4 leases.
virtual void updateLease4(const Lease4Ptr &lease4)=0
Updates IPv4 lease.
virtual Lease6Ptr getLease6(Lease::Type type, const isc::asiolink::IOAddress &addr) const =0
Returns existing IPv6 lease for a given IPv6 address.
virtual void updateLease6(const Lease6Ptr &lease6)=0
Updates IPv6 lease.
static void packOptions6(isc::util::OutputBuffer &buf, const isc::dhcp::OptionCollection &options)
Stores DHCPv6 options in a buffer.
Attempt to update lease that was not there.
static std::string makeLabel(const HWAddrPtr &hwaddr, const ClientIdPtr &client_id, const uint32_t transid)
Returns text representation of the given packet identifiers.
static std::string makeLabel(const DuidPtr duid, const uint32_t transid, const HWAddrPtr &hwaddr)
Returns text representation of the given packet identifiers.
bool tryLock4(const asiolink::IOAddress &addr)
Tries to acquires a resource.
bool tryLock(Lease::Type type, const asiolink::IOAddress &addr)
Tries to acquires a resource.
RAII object enabling copying options retrieved from the packet.
static bool subnetsIncludeMatchClientId(const ConstSubnet4Ptr &first_subnet, const ClientClasses &client_classes)
Checks if the shared network includes a subnet with the match client ID flag set to true.
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_CONTINUE
continue normally
@ NEXT_STEP_SKIP
skip the next processing step
static int registerHook(const std::string &name)
Register Hook.
static bool calloutsPresent(int index)
Are callouts present?
static boost::shared_ptr< CalloutHandle > createCalloutHandle()
Return callout handle.
static void callCallouts(int index, CalloutHandle &handle)
Calls the callouts for a given hook.
Wrapper class around callout handle which automatically resets handle's state.
static StatsMgr & instance()
Statistics Manager accessor method.
static std::string generateName(const std::string &context, Type index, const std::string &stat_name)
Generates statistic name in a given context.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
bool getMode() const
Get the multi-threading mode.
A template representing an optional value.
T get() const
Retrieves the encapsulated value.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
const uint8_t * getData() const
Return a pointer to the head of the data stored in the buffer.
size_t getLength() const
Return the length of data written in the buffer.
Utility class to measure code execution times.
long getTotalMilliseconds() const
Retrieves the total measured duration in milliseconds.
void stop()
Stops the stopwatch.
std::string logFormatTotalDuration() const
Returns the total measured duration in the format directly usable in the log messages.
This template specifies a parameter value.
T get(T hint) const
Returns value with a hint.
Write mutex RAII handler.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< OptionUint32 > OptionUint32Ptr
void addValue(const std::string &name, const int64_t value)
Records incremental integer observation.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
boost::shared_ptr< const Element > ConstElementPtr
boost::shared_ptr< Element > ElementPtr
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_INVALID
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAMATION_FAILED
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_NO_POOLS
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS6
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RECOVER_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_IN_USE
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_HR
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_PREFIX_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_NO_V6_HR
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_SHARED_ADDR_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_ERROR
const isc::log::MessageID ALLOC_ENGINE_V6_HINT_RESERVED
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_SLOW
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED
isc::log::Logger alloc_engine_logger("alloc-engine")
Logger for the AllocEngine.
void queueNCR(const NameChangeType &chg_type, const Lease4Ptr &lease)
Creates name change request from the DHCPv4 lease.
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE
const isc::log::MessageID ALLOC_ENGINE_LEASE_RECLAIMED
const int ALLOC_ENGINE_DBG_TRACE
Logging levels for the AllocEngine.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_COMPLETE
const isc::log::MessageID ALLOC_ENGINE_IGNORING_UNSUITABLE_GLOBAL_ADDRESS
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_COMPLETE
std::vector< ConstHostPtr > ConstHostCollection
Collection of the const Host objects.
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ERROR
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_HR
boost::shared_ptr< DUID > DuidPtr
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED
boost::shared_ptr< Lease6 > Lease6Ptr
Pointer to a Lease6 structure.
std::vector< Lease6Ptr > Lease6Collection
A collection of IPv6 leases.
const isc::log::MessageID ALLOC_ENGINE_V4_DECLINED_RECOVERED
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_SELECT_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_SLOW
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_USE_HR
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_TIMEOUT
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_START
boost::shared_ptr< Option6IAPrefix > Option6IAPrefixPtr
Pointer to the Option6IAPrefix object.
const isc::log::MessageID ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED
std::pair< IPv6ResrvIterator, IPv6ResrvIterator > IPv6ResrvRange
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAIM
const isc::log::MessageID ALLOC_ENGINE_V4_LEASE_RECLAIM
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_HR
boost::shared_ptr< HWAddr > HWAddrPtr
Shared pointer to a hardware address structure.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_TIMEOUT
const isc::log::MessageID DHCPSRV_CFGMGR_IP_RESERVATIONS_UNIQUE_DUPLICATES_DETECTED
const isc::log::MessageID ALLOC_ENGINE_V6_HR_ADDR_GRANTED
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_CLASSES
const isc::log::MessageID ALLOC_ENGINE_V6_NO_MORE_EXPIRED_LEASES
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
const isc::log::MessageID ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_ERROR
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_ADDR_LEASE
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_NO_POOLS
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SHARED_NETWORK
const isc::log::MessageID ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
const int ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA
Records detailed results of various operations.
const int DHCPSRV_DBG_HOOKS
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE_COMPLETE
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
const isc::log::MessageID ALLOC_ENGINE_V6_REVOKED_PREFIX_LEASE
boost::shared_ptr< ClientId > ClientIdPtr
Shared pointer to a Client ID.
const isc::log::MessageID ALLOC_ENGINE_V4_NO_MORE_EXPIRED_LEASES
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_EXTEND_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS
const isc::log::MessageID ALLOC_ENGINE_V4_OFFER_NEW_LEASE
boost::shared_ptr< Option6IAAddr > Option6IAAddrPtr
A pointer to the isc::dhcp::Option6IAAddr object.
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_SELECT_SKIP
boost::shared_ptr< const Host > ConstHostPtr
Const pointer to the Host object.
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL
const isc::log::MessageID DHCPSRV_HOOK_LEASE6_RECOVER_SKIP
const isc::log::MessageID ALLOC_ENGINE_V4_RECLAIMED_LEASES_DELETE_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_COMPLETE
const isc::log::MessageID ALLOC_ENGINE_V4_LEASES_RECLAMATION_FAILED
const isc::log::MessageID ALLOC_ENGINE_V6_CALCULATED_PREFERRED_LIFETIME
void deleteAssignedLease(Lease4Ptr lease)
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_UNRESERVED
const isc::log::MessageID ALLOC_ENGINE_V6_DECLINED_RECOVERED
boost::shared_ptr< const Subnet > ConstSubnetPtr
A generic pointer to either const Subnet4 or const Subnet6 object.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASES_RECLAMATION_START
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
const isc::log::MessageID ALLOC_ENGINE_V6_LEASE_RECLAMATION_FAILED
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
std::vector< Lease4Ptr > Lease4Collection
A collection of IPv4 leases.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SUBNET
const isc::log::MessageID ALLOC_ENGINE_V4_DISCOVER_ADDRESS_CONFLICT
const isc::log::MessageID DHCPSRV_HOOK_LEASE4_RENEW_SKIP
boost::shared_ptr< Lease4 > Lease4Ptr
Pointer to a Lease4 structure.
const isc::log::MessageID ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE
const isc::log::MessageID ALLOC_ENGINE_V6_RECLAIMED_LEASES_DELETE
boost::shared_ptr< Option > OptionPtr
const isc::log::MessageID ALLOC_ENGINE_V6_ALLOC_FAIL_SUBNET
const int ALLOC_ENGINE_DBG_TRACE_DETAIL
Record detailed traces.
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_SHARED_NETWORK
const isc::log::MessageID ALLOC_ENGINE_V6_HR_PREFIX_GRANTED
const isc::log::MessageID ALLOC_ENGINE_V4_ALLOC_FAIL_CLASSES
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
boost::shared_ptr< CalloutHandle > CalloutHandlePtr
A shared pointer to a CalloutHandle object.
string encodeHex(const vector< uint8_t > &binary)
Encode binary data in the base16 format.
boost::multiprecision::checked_uint128_t uint128_t
Defines the logger used by the top-level component of kea-lfc.
This file provides the classes needed to embody, compose, and decompose DNS update requests that are ...
Context information for the DHCPv4 lease allocation.
ClientIdPtr clientid_
Client identifier from the DHCP message.
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
ConstHostPtr currentHost() const
Returns host for currently selected subnet.
ClientContext4()
Default constructor.
Pkt4Ptr query_
A pointer to the client's message.
Lease4Ptr new_lease_
A pointer to a newly allocated lease.
std::string hostname_
Hostname.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
ConstSubnet4Ptr subnet_
Subnet selected for the client by the server.
bool rev_dns_update_
Perform reverse DNS update.
uint32_t offer_lft_
If not zero, then we will allocate on DISCOVER for this amount of time.
bool fake_allocation_
Indicates if this is a real or fake allocation.
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
bool unknown_requested_addr_
True when the address DHCPREQUEST'ed by client is not within a dynamic pool the server knows about.
Lease4Ptr old_lease_
A pointer to an old lease that the client had before update.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
bool fwd_dns_update_
Perform forward DNS update.
asiolink::IOAddress requested_address_
An address that the client desires.
Lease4Ptr conflicting_lease_
A pointer to the object representing a lease in conflict.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
HWAddrPtr hwaddr_
HW address from the DHCP message.
IAContext()
Default constructor.
Lease6Collection old_leases_
A pointer to any old leases that the client had before update but are no longer valid after the updat...
Option6IAPtr ia_rsp_
A pointer to the IA_NA/IA_PD option to be sent in response.
Lease::Type type_
Lease type (IA or PD)
ResourceContainer new_resources_
Holds addresses and prefixes allocated for this IA.
bool isNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was new.
Lease6Collection changed_leases_
A pointer to any leases that have changed FQDN information.
void addHint(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128, const uint32_t preferred=0, const uint32_t valid=0)
Convenience method adding new hint.
void addNewResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding new prefix or address.
Lease6Collection reused_leases_
Set of leases marked for reuse by lease caching.
HintContainer hints_
Client's hints.
uint32_t iaid_
The IAID field from IA_NA or IA_PD that is being processed.
Context information for the DHCPv6 leases allocation.
IAContext & currentIA()
Returns IA specific context for the currently processed IA.
std::vector< IAContext > ias_
Container holding IA specific contexts.
void addHostIdentifier(const Host::IdentifierType &id_type, const std::vector< uint8_t > &identifier)
Convenience function adding host identifier into host_identifiers_ list.
bool fake_allocation_
Indicates if this is a real or fake allocation.
ConstHostPtr currentHost() const
Returns host from the most preferred subnet.
ClientContext6()
Default constructor.
DuidPtr duid_
Client identifier.
void addAllocatedResource(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128)
Convenience method adding allocated prefix or address.
Lease6Collection new_leases_
A collection of newly allocated leases.
HWAddrPtr hwaddr_
Hardware/MAC address (if available, may be NULL)
hooks::CalloutHandlePtr callout_handle_
Callout handle associated with the client's message.
bool isAllocated(const asiolink::IOAddress &prefix, const uint8_t prefix_len=128) const
Checks if specified address or prefix was allocated.
bool hasGlobalReservation(const IPv6Resrv &resv) const
Determines if a global reservation exists.
ResourceContainer allocated_resources_
Holds addresses and prefixes allocated for all IAs.
bool rev_dns_update_
A boolean value which indicates that server takes responsibility for the reverse DNS Update for this ...
DdnsParamsPtr getDdnsParams()
Returns the set of DDNS behavioral parameters based on the selected subnet.
ConstHostPtr globalHost() const
Returns global host reservation if there is one.
Pkt6Ptr query_
A pointer to the client's message.
bool early_global_reservations_lookup_
Indicates if early global reservation is enabled.
std::string hostname_
Hostname.
ConstSubnet6Ptr host_subnet_
Subnet from which host reservations should be retrieved.
IdentifierList host_identifiers_
A list holding host identifiers extracted from a message received by the server.
ConstSubnet6Ptr subnet_
Subnet selected for the client by the server.
std::map< SubnetID, ConstHostPtr > hosts_
Holds a map of hosts belonging to the client within different subnets.
bool fwd_dns_update_
A boolean value which indicates that server takes responsibility for the forward DNS Update for this ...
Structure that holds a lease for IPv6 address and/or prefix.
@ ACTION_UPDATE
update extended info tables.
@ ACTION_DELETE
delete reference to the lease
@ ACTION_IGNORE
ignore extended info,
a common structure for IPv4 and IPv6 leases
static const uint32_t INFINITY_LFT
Infinity (means static, i.e. never expire)
static const uint32_t STATE_DEFAULT
A lease in the default state.
static const uint32_t STATE_DECLINED
Declined lease.
static const uint32_t STATE_RELEASED
Released lease held in the database for lease affinity.
static const uint32_t STATE_EXPIRED_RECLAIMED
Expired and reclaimed lease.
Type
Type of lease or pool.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
static const uint32_t STATE_REGISTERED
Registered self-generated lease.