Browse Source

[3852] Added traces to the allocation engine.

Marcin Siodelski 10 years ago
parent
commit
b043038e7c

+ 2 - 0
src/bin/dhcp4/dhcp4_srv.cc

@@ -109,6 +109,8 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
     context_->subnet_ = subnet;
     context_->subnet_ = subnet;
     // Hardware address.
     // Hardware address.
     context_->hwaddr_ = query->getHWAddr();
     context_->hwaddr_ = query->getHWAddr();
+    // Pointer to client's query.
+    context_->query_ = query;
 
 
     // Set client identifier if the match-client-id flag is enabled (default).
     // Set client identifier if the match-client-id flag is enabled (default).
     // If the subnet wasn't found it doesn't matter because we will not be
     // If the subnet wasn't found it doesn't matter because we will not be

+ 3 - 0
src/bin/dhcp6/dhcp6_srv.cc

@@ -285,6 +285,7 @@ Dhcpv6Srv::createContext(const Pkt6Ptr& pkt) {
     ctx.subnet_ = selectSubnet(pkt);
     ctx.subnet_ = selectSubnet(pkt);
     ctx.duid_ = pkt->getClientId();
     ctx.duid_ = pkt->getClientId();
     ctx.hwaddr_ = getMAC(pkt);
     ctx.hwaddr_ = getMAC(pkt);
+    ctx.query_ = pkt;
     alloc_engine_->findReservation(ctx);
     alloc_engine_->findReservation(ctx);
 
 
     return (ctx);
     return (ctx);
@@ -1406,6 +1407,7 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
     ctx.callout_handle_ = getCalloutHandle(query);
     ctx.callout_handle_ = getCalloutHandle(query);
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.host_ = orig_ctx.host_;
     ctx.host_ = orig_ctx.host_;
+    ctx.query_ = orig_ctx.query_;
 
 
     Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
     Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
 
 
@@ -1566,6 +1568,7 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
     ctx.callout_handle_ = getCalloutHandle(query);
     ctx.callout_handle_ = getCalloutHandle(query);
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.host_ = orig_ctx.host_;
     ctx.host_ = orig_ctx.host_;
+    ctx.query_ = orig_ctx.query_;
 
 
     Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
     Lease6Collection leases = alloc_engine_->allocateLeases6(ctx);
 
 

+ 120 - 2
src/lib/dhcpsrv/alloc_engine.cc

@@ -381,6 +381,10 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
         // Case 1: There are no leases and there's a reservation for this host.
         // Case 1: There are no leases and there's a reservation for this host.
         if (leases.empty() && ctx.host_) {
         if (leases.empty() && ctx.host_) {
 
 
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR)
+                .arg(ctx.query_->getLabel());
+
             // Try to allocate leases that match reservations. Typically this will
             // Try to allocate leases that match reservations. Typically this will
             // succeed, except cases where the reserved addresses are used by
             // succeed, except cases where the reserved addresses are used by
             // someone else.
             // someone else.
@@ -406,6 +410,10 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
         // FQDN information.
         // FQDN information.
         } else if (!leases.empty() && !ctx.host_) {
         } else if (!leases.empty() && !ctx.host_) {
 
 
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR)
+                .arg(ctx.query_->getLabel());
+
             // Check if the existing leases are reserved for someone else.
             // Check if the existing leases are reserved for someone else.
             // If they're not, we're ok to keep using them.
             // If they're not, we're ok to keep using them.
             removeNonmatchingReservedLeases6(ctx, leases);
             removeNonmatchingReservedLeases6(ctx, leases);
@@ -424,6 +432,10 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
         // Case 3: There are leases and there are reservations.
         // Case 3: There are leases and there are reservations.
         } else if (!leases.empty() && ctx.host_) {
         } else if (!leases.empty() && ctx.host_) {
 
 
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_ALLOC_LEASES_HR)
+                .arg(ctx.query_->getLabel());
+
             // First, check if have leases matching reservations, and add new
             // First, check if have leases matching reservations, and add new
             // leases if we don't have them.
             // leases if we don't have them.
             allocateReservedLeases6(ctx, leases);
             allocateReservedLeases6(ctx, leases);
@@ -478,6 +490,10 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
         // for now. This is also a catch-all or last resort approach, when we
         // for now. This is also a catch-all or last resort approach, when we
         // couldn't find any reservations (or couldn't use them).
         // couldn't find any reservations (or couldn't use them).
 
 
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V6_ALLOC_UNRESERVED)
+            .arg(ctx.query_->getLabel());
+
         leases = allocateUnreservedLeases6(ctx);
         leases = allocateUnreservedLeases6(ctx);
 
 
         if (!leases.empty()) {
         if (!leases.empty()) {
@@ -1024,12 +1040,21 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
             .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID());
             .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID());
 
 
         if (!leases.empty()) {
         if (!leases.empty()) {
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED)
+                .arg(ctx.query_->getLabel());
+
             // Check if the existing leases are reserved for someone else.
             // Check if the existing leases are reserved for someone else.
             // If they're not, we're ok to keep using them.
             // If they're not, we're ok to keep using them.
             removeNonmatchingReservedLeases6(ctx, leases);
             removeNonmatchingReservedLeases6(ctx, leases);
         }
         }
 
 
         if (ctx.host_) {
         if (ctx.host_) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_RENEW_HR)
+                .arg(ctx.query_->getLabel());
+
             // If we have host reservation, allocate those leases.
             // If we have host reservation, allocate those leases.
             allocateReservedLeases6(ctx, leases);
             allocateReservedLeases6(ctx, leases);
 
 
@@ -1045,11 +1070,21 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
         // new leases during renewals. This is controlled with the
         // new leases during renewals. This is controlled with the
         // allow_new_leases_in_renewals_ field.
         // allow_new_leases_in_renewals_ field.
         if (leases.empty() && ctx.allow_new_leases_in_renewals_) {
         if (leases.empty() && ctx.allow_new_leases_in_renewals_) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED)
+                .arg(ctx.query_->getLabel());
+
             leases = allocateUnreservedLeases6(ctx);
             leases = allocateUnreservedLeases6(ctx);
         }
         }
 
 
         // Extend all existing leases that passed all checks.
         // Extend all existing leases that passed all checks.
         for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
         for (Lease6Collection::iterator l = leases.begin(); l != leases.end(); ++l) {
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL,
+                      ALLOC_ENGINE_V6_EXTEND_LEASE)
+                .arg(ctx.query_->getLabel())
+                .arg((*l)->typeToText((*l)->type_))
+                .arg((*l)->addr_);
             extendLease6(ctx, *l);
             extendLease6(ctx, *l);
         }
         }
 
 
@@ -1058,7 +1093,9 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
     } catch (const isc::Exception& e) {
     } catch (const isc::Exception& e) {
 
 
         // Some other error, return an empty lease.
         // Some other error, return an empty lease.
-        LOG_ERROR(dhcpsrv_logger, DHCPSRV_RENEW6_ERROR).arg(e.what());
+        LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_V6_EXTEND_ERROR)
+            .arg(ctx.query_->getLabel())
+            .arg(e.what());
     }
     }
 
 
     return (Lease6Collection());
     return (Lease6Collection());
@@ -1071,6 +1108,11 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
         return;
         return;
     }
     }
 
 
+    LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
+              ALLOC_ENGINE_V6_EXTEND_LEASE_DATA)
+        .arg(ctx.query_->getLabel())
+        .arg(lease->toText());
+
     // Check if the lease still belongs to the subnet. If it doesn't,
     // Check if the lease still belongs to the subnet. If it doesn't,
     // we'll need to remove it.
     // we'll need to remove it.
     if ((lease->type_ != Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) {
     if ((lease->type_ != Lease::TYPE_PD) && !ctx.subnet_->inRange(lease->addr_)) {
@@ -1098,6 +1140,11 @@ AllocEngine::extendLease6(ClientContext6& ctx, Lease6Ptr lease) {
     lease->fqdn_rev_ = ctx.rev_dns_update_;
     lease->fqdn_rev_ = ctx.rev_dns_update_;
     lease->hwaddr_ = ctx.hwaddr_;
     lease->hwaddr_ = ctx.hwaddr_;
 
 
+    LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
+              ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA)
+        .arg(ctx.query_->getLabel())
+        .arg(lease->toText());
+
     bool skip = false;
     bool skip = false;
     // Get the callouts specific for the processed message and execute them.
     // Get the callouts specific for the processed message and execute them.
     int hook_point = ctx.query_->getType() == DHCPV6_RENEW ?
     int hook_point = ctx.query_->getType() == DHCPV6_RENEW ?
@@ -1278,7 +1325,7 @@ AllocEngine::ClientContext4::ClientContext4()
       requested_address_(IOAddress::IPV4_ZERO_ADDRESS()),
       requested_address_(IOAddress::IPV4_ZERO_ADDRESS()),
       fwd_dns_update_(false), rev_dns_update_(false),
       fwd_dns_update_(false), rev_dns_update_(false),
       hostname_(""), callout_handle_(), fake_allocation_(false),
       hostname_(""), callout_handle_(), fake_allocation_(false),
-      old_lease_(), host_(), conflicting_lease_() {
+      old_lease_(), host_(), conflicting_lease_(), query_() {
 }
 }
 
 
 AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
 AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
@@ -1363,6 +1410,12 @@ AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
     // Check if there is a reservation for the client. If there is, we want to
     // Check if there is a reservation for the client. If there is, we want to
     // assign the reserved address, rather than any other one.
     // assign the reserved address, rather than any other one.
     if (hasAddressReservation(ctx)) {
     if (hasAddressReservation(ctx)) {
+
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_DISCOVER_HR)
+            .arg(ctx.query_->getLabel())
+            .arg(ctx.host_->getIPv4Reservation().toText());
+
         // If the client doesn't have a lease or the leased address is different
         // If the client doesn't have a lease or the leased address is different
         // than the reserved one then let's try to allocate the reserved address.
         // than the reserved one then let's try to allocate the reserved address.
         // Otherwise the address that the client has is the one for which it
         // Otherwise the address that the client has is the one for which it
@@ -1400,6 +1453,10 @@ AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
         ctx.subnet_->inPool(Lease::TYPE_V4, client_lease->addr_) &&
         ctx.subnet_->inPool(Lease::TYPE_V4, client_lease->addr_) &&
         !addressReserved(client_lease->addr_, ctx)) {
         !addressReserved(client_lease->addr_, ctx)) {
 
 
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE)
+            .arg(ctx.query_->getLabel());
+
         new_lease = renewLease4(client_lease, ctx);
         new_lease = renewLease4(client_lease, ctx);
     }
     }
 
 
@@ -1414,6 +1471,10 @@ AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
         ctx.subnet_->inPool(Lease::TYPE_V4, ctx.requested_address_) &&
         ctx.subnet_->inPool(Lease::TYPE_V4, ctx.requested_address_) &&
         !addressReserved(ctx.requested_address_, ctx)) {
         !addressReserved(ctx.requested_address_, ctx)) {
 
 
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_OFFER_NEW_LEASE)
+            .arg(ctx.query_->getLabel());
+
         new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
         new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
     }
     }
 
 
@@ -1421,6 +1482,11 @@ AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
     // addresses. We will now use the allocator to pick the address
     // addresses. We will now use the allocator to pick the address
     // from the dynamic pool.
     // from the dynamic pool.
     if (!new_lease) {
     if (!new_lease) {
+
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_OFFER_NEW_LEASE)
+            .arg(ctx.query_->getLabel());
+
         new_lease = allocateUnreservedLease4(ctx);
         new_lease = allocateUnreservedLease4(ctx);
     }
     }
 
 
@@ -1456,6 +1522,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
         // is not reserved for another client. If it is, stop here because
         // is not reserved for another client. If it is, stop here because
         // we can't allocate this address.
         // we can't allocate this address.
         if (addressReserved(ctx.requested_address_, ctx)) {
         if (addressReserved(ctx.requested_address_, ctx)) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED)
+                .arg(ctx.query_->getLabel())
+                .arg(ctx.requested_address_.toText());
+
             return (Lease4Ptr());
             return (Lease4Ptr());
         }
         }
 
 
@@ -1465,6 +1537,11 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
         // If there is a reservation for the client, let's try to
         // If there is a reservation for the client, let's try to
         // allocate the reserved address.
         // allocate the reserved address.
         ctx.requested_address_ = ctx.host_->getIPv4Reservation();
         ctx.requested_address_ = ctx.host_->getIPv4Reservation();
+
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_REQUEST_USE_HR)
+            .arg(ctx.query_->getLabel())
+            .arg(ctx.requested_address_.toText());
     }
     }
 
 
     if (!ctx.requested_address_.isV4Zero()) {
     if (!ctx.requested_address_.isV4Zero()) {
@@ -1477,6 +1554,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
         // allocated.
         // allocated.
         if (existing && !existing->expired() &&
         if (existing && !existing->expired() &&
             !existing->belongsToClient(ctx.hwaddr_, ctx.clientid_)) {
             !existing->belongsToClient(ctx.hwaddr_, ctx.clientid_)) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V4_REQUEST_IN_USE)
+                .arg(ctx.query_->getLabel())
+                .arg(ctx.requested_address_.toText());
+
             return (Lease4Ptr());
             return (Lease4Ptr());
         }
         }
 
 
@@ -1492,6 +1575,13 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
             // address, return NULL. The client should go back to the
             // address, return NULL. The client should go back to the
             // DHCPDISCOVER and the reserved address will be offered.
             // DHCPDISCOVER and the reserved address will be offered.
             if (!existing || existing->expired()) {
             if (!existing || existing->expired()) {
+
+                LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                          ALLOC_ENGINE_V4_REQUEST_INVALID)
+                    .arg(ctx.query_->getLabel())
+                    .arg(ctx.host_->getIPv4Reservation().toText())
+                    .arg(ctx.requested_address_.toText());
+
                 return (Lease4Ptr());
                 return (Lease4Ptr());
             }
             }
         }
         }
@@ -1502,6 +1592,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
         if ((!hasAddressReservation(ctx) ||
         if ((!hasAddressReservation(ctx) ||
              (ctx.host_->getIPv4Reservation() != ctx.requested_address_)) &&
              (ctx.host_->getIPv4Reservation() != ctx.requested_address_)) &&
             !ctx.subnet_->inPool(Lease4::TYPE_V4, ctx.requested_address_)) {
             !ctx.subnet_->inPool(Lease4::TYPE_V4, ctx.requested_address_)) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL)
+                .arg(ctx.query_->getLabel())
+                .arg(ctx.requested_address_);
+
             return (Lease4Ptr());
             return (Lease4Ptr());
         }
         }
     }
     }
@@ -1515,6 +1611,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
     if (client_lease) {
     if (client_lease) {
         if ((client_lease->addr_ == ctx.requested_address_) ||
         if ((client_lease->addr_ == ctx.requested_address_) ||
             ctx.requested_address_.isV4Zero()) {
             ctx.requested_address_.isV4Zero()) {
+
+            LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                      ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE)
+                .arg(ctx.query_->getLabel())
+                .arg(ctx.requested_address_);
+
             return (renewLease4(client_lease, ctx));
             return (renewLease4(client_lease, ctx));
         }
         }
     }
     }
@@ -1526,6 +1628,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
     // The client doesn't have the lease or it is requesting an address
     // The client doesn't have the lease or it is requesting an address
     // which it doesn't have. Let's try to allocate the requested address.
     // which it doesn't have. Let's try to allocate the requested address.
     if (!ctx.requested_address_.isV4Zero()) {
     if (!ctx.requested_address_.isV4Zero()) {
+
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED)
+            .arg(ctx.query_->getLabel())
+            .arg(ctx.requested_address_.toText());
+
         // The call below will return a pointer to the lease allocated
         // The call below will return a pointer to the lease allocated
         // for the client if there is no lease for the requested address,
         // for the client if there is no lease for the requested address,
         // or the existing lease has expired. If the allocation fails,
         // or the existing lease has expired. If the allocation fails,
@@ -1535,6 +1643,10 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
 
 
     } else {
     } else {
 
 
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS)
+            .arg(ctx.query_->getLabel());
+
         // We will only get here if the client didn't specify which
         // We will only get here if the client didn't specify which
         // address it wanted to be allocated. The allocation engine will
         // address it wanted to be allocated. The allocation engine will
         // to pick the address from the dynamic pool.
         // to pick the address from the dynamic pool.
@@ -1546,6 +1658,12 @@ AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
     // the previous lease needs to be removed from the lease database.
     // the previous lease needs to be removed from the lease database.
     if (new_lease && client_lease) {
     if (new_lease && client_lease) {
         ctx.old_lease_ = Lease4Ptr(new Lease4(*client_lease));
         ctx.old_lease_ = Lease4Ptr(new Lease4(*client_lease));
+
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE)
+            .arg(ctx.query_->getLabel())
+            .arg(client_lease->addr_.toText());
+
         lease_mgr.deleteLease(client_lease->addr_);
         lease_mgr.deleteLease(client_lease->addr_);
     }
     }
 
 

+ 7 - 0
src/lib/dhcpsrv/alloc_engine.h

@@ -18,6 +18,7 @@
 #include <asiolink/io_address.h>
 #include <asiolink/io_address.h>
 #include <dhcp/duid.h>
 #include <dhcp/duid.h>
 #include <dhcp/hwaddr.h>
 #include <dhcp/hwaddr.h>
+#include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/option6_ia.h>
 #include <dhcp/option6_ia.h>
 #include <dhcpsrv/host.h>
 #include <dhcpsrv/host.h>
@@ -737,6 +738,12 @@ public:
         /// which is in conflict with this allocation.
         /// which is in conflict with this allocation.
         Lease4Ptr conflicting_lease_;
         Lease4Ptr conflicting_lease_;
 
 
+        /// @brief A pointer to the client's message.
+        ///
+        /// This is used in logging to retrieve the client's and the
+        /// transaction identification information.
+        Pkt4Ptr query_;
+
         /// @brief Default constructor.
         /// @brief Default constructor.
         ClientContext4();
         ClientContext4();
 
 

+ 152 - 1
src/lib/dhcpsrv/alloc_engine_messages.mes

@@ -84,4 +84,155 @@ A has been told to stop using it so that it can be leased to client B.
 This is a normal occurrence during conflict resolution, which can occur
 This is a normal occurrence during conflict resolution, which can occur
 in cases such as the system administrator adding a reservation for an
 in cases such as the system administrator adding a reservation for an
 address that is currently in use by another client.  The server will fully
 address that is currently in use by another client.  The server will fully
-recover from this situation, but clients will change their prefixes.
+recover from this situation, but clients will change their prefixes.
+
+% ALLOC_ENGINE_V4_DISCOVER_HR %1: client sending DHCPDISCOVER has reservation for the address %2
+This message is issued when the allocation engine determines that the
+client sending the DHCPDISCOVER has a reservation for the specified
+address. The allocation engine will try to offer this address to
+the client.
+
+% ALLOC_ENGINE_V4_OFFER_EXISTING_LEASE %1: allocation engine will try to offer existing lease to the client
+This message is issued when the allocation engine determines that
+the client has a lease in the lease database, it doesn't have
+reservation for any other lease, and the leased address is not
+reserved for any other client. The allocation engine will try
+to offer the same lease to the client.
+
+% ALLOC_ENGINE_V4_OFFER_NEW_LEASE %1: allocation engine will try to offer new lease to the client
+This message is issued when the allocation engine will try to
+offer new lease to the client. This is the case when the
+client doesn't have any existing lease, it has no reservation
+or the existing or reserved address is leased to another client.
+Also, the client didn't specify the hint, or the address in
+the hint is in use.
+
+% ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE %1: allocation engine will try to offer requested lease to the client
+This message is issued when the allocation engine will try to
+offer lease specified in the hint, because the client doesn't
+have any reservations or the reserved or currently allocated
+address is leased to another client.
+
+% ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED %1: requested address is reserved
+This message is issued when the allocation engine refused to
+allocate address requested by the client, because this
+address is reserved for another client.
+
+% ALLOC_ENGINE_V4_REQUEST_ALLOC_REQUESTED %1: trying to allocate requested address %2
+This message is issued when the allocation engine is trying
+to allocate (or reuse expired) address which has been
+requested by the client.
+
+% ALLOC_ENGINE_V4_REQUEST_EXTEND_LEASE %1: extending lifetime of the lease for address %2
+This message is issued when the allocation engine determines
+that the client already has a lease which lifetime can be
+extended, and which can be returned to the client.
+
+% ALLOC_ENGINE_V4_REQUEST_IN_USE %1: requested address %2 is in use
+This message is issued when the client is requesting or has a
+reservation for an address which is in use.
+
+% ALLOC_ENGINE_V4_REQUEST_INVALID %1: client having a reservation for address %2 is requesting invalid address %3
+This message is logged when the client having a reservation for
+one address, is requesting a different address. The client is
+only allowed to do it when the reserved address is in use by
+another client. However, the allocation engine has now
+determined that the reserved address is available and the
+client should request the reserved address.
+
+% ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL %1: client which doesn't have reservation requested address of the dynamic pool
+This message is issued when the client has requested allocation
+of the address which doesn't belong to any address pool from
+which addresses are dynamically allocated. The client also
+doesn't have reservation for this address. This address
+could only be allocated if the client had reservation for it.
+
+% ALLOC_ENGINE_V4_REQUEST_PICK_ADDRESS %1: client hasn't requested any address - picking available address from the pool
+This message is logged when the client hasn't specified any address
+to be allocated. Client should always do it, but we want to be
+liberal. The allocation engine will try to pick an available
+address from the dynamic pool and allocate to the client.
+
+% ALLOC_ENGINE_V4_REQUEST_REMOVE_LEASE %1: removing previous client's lease %2
+This message is logged when the allocation engine removes previous
+lease for the client, because the cliet has been allocated new
+lease.
+
+% ALLOC_ENGINE_V4_REQUEST_USE_HR %1: client hasn't requested specific address, using reserved address %2
+This message is issued when the client is not requesting any specific
+address and the allocation engine determines that there is a
+reservation for this client. The allocation engine will try to
+allocate the reserved address.
+
+% ALLOC_ENGINE_V6_ALLOC_LEASES_HR %1: leases and static reservations found for client
+This message is logged when the allocation engine is in the process of
+allocating leases for the client, it found existing leases and static
+reservations for the client. The allocation angine will verify if
+existing leases match reservations. Those leases that are reserved for
+other clients and those that are not reserved for the client will
+be removed. All leases matching the reservations will be renewed
+and returned.
+
+% ALLOC_ENGINE_V6_ALLOC_NO_LEASES_HR %1: no leases found but reservations exist for client
+This message is logged when the allocation engine is in the process of
+allocating leases for the client, it hasn't found any existing leases
+for this client, but the client appears to have static reservations.
+The allocation engine will try to allocate the reserved resources for
+the client.
+
+% ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR %1: no reservations found but leases exist for client
+This message is logged when the allocation engine is in the process if
+allocating leases for the client, there are no static reservations,
+but lease(s) exist for the client. The allocation engine will remove
+leases which are reserved for other clients, and return all
+remaning leases to the client.
+
+% ALLOC_ENGINE_V6_ALLOC_UNRESERVED %1: no static reservations: trying to dynamically allocate leases
+This debug message is issued when the allocation engine will attempt
+to allocate leases from the dynamic pools, rather than reserved
+leases.
+
+% ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED %1: allocate new (unreserved) leases for the renewing client
+This debug message is issued when the allocation engine is trying to
+allocate new leases for the renewing client, because it was unable to
+renew any of the existing client's leases, e.g. because leases are
+reserved for another client or for any other reason.
+
+% ALLOC_ENGINE_V6_EXTEND_LEASE %1: extending lifetime of the lease type %2, address %3
+This debug message is issued when the allocation engine is trying
+to extend lifetime of the lease.
+
+% ALLOC_ENGINE_V6_EXTEND_LEASE_DATA %1: detailed information about the lease being extended: %2
+This debug message prints detailed information about the lease which
+lifetime is being extended (renew or rebind).
+
+% ALLOC_ENGINE_V6_EXTEND_NEW_LEASE_DATA %1: new lease information for the lease being extended: %2
+This debug message prints updated information about the lease to be
+extended. If the lease update is successful, the information printed
+by this message will be stored in the database for this lease.
+
+% ALLOC_ENGINE_V6_EXTEND_ERROR %1: allocation engine experienced error with attempting to extend lease lifetime: %2
+This error message indicates that an error was experienced during Renew
+or Rebind processing. Additional explanation is provided with this
+message. Depending on its nature, manual intervention may be required to
+continue processing messages from this particular client; other clients
+will be unaffected.
+
+% ALLOC_ENGINE_V6_RENEW_HR %1: allocating leases reserved for the client as a result of Renew
+This debug message is issued when the allocation engine will try to
+allocate reserved leases for the client sending a Renew message.
+The server will also remove any leases that the client is trying
+to renew, which are not reserved for the client.
+
+% ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED %1: checking if existing client's leases are reseved for another client
+This message is logged when the allocation engine finds leases for
+the client and will check if these leases are reserved for another
+client. If they are, they will not be renewed for the client
+requsting their renewal.
+
+% ALLOC_ENGINE_V6_RENEW_REMOVE_UNRESERVED %1: dynamically allocating leases for the renewing client
+This debug message is issued when the allocation engine is trying
+to dynamically allocate new leases for the renewing client. This
+is the case when the server couldn't renew any of the existing
+client's leases, e.g. because leased resources are reserved for
+another client.

+ 0 - 7
src/lib/dhcpsrv/dhcpsrv_messages.mes

@@ -527,13 +527,6 @@ lease from the PostgreSQL database for the specified address.
 A debug message issued when the server is attempting to update IPv6
 A debug message issued when the server is attempting to update IPv6
 lease from the PostgreSQL database for the specified address.
 lease from the PostgreSQL database for the specified address.
 
 
-% DHCPSRV_RENEW6_ERROR allocation engine experienced error with attempting to renew a lease: %1
-This error message indicates that an error was experienced during Renew
-or Rebind processing. Additional explanation is provided with this
-message. Depending on its nature, manual intervention may be required to
-continue processing messages from this particular client; other clients
-will be unaffected.
-
 % DHCPSRV_UNEXPECTED_NAME database access parameters passed through '%1', expected 'lease-database'
 % DHCPSRV_UNEXPECTED_NAME database access parameters passed through '%1', expected 'lease-database'
 The parameters for access the lease database were passed to the server through
 The parameters for access the lease database were passed to the server through
 the named configuration parameter, but the code was expecting them to be
 the named configuration parameter, but the code was expecting them to be

+ 44 - 0
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc

@@ -13,6 +13,7 @@
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
 #include <config.h>
 #include <config.h>
+#include <dhcp/pkt4.h>
 #include <dhcpsrv/tests/alloc_engine_utils.h>
 #include <dhcpsrv/tests/alloc_engine_utils.h>
 #include <dhcpsrv/tests/test_utils.h>
 #include <dhcpsrv/tests/test_utils.h>
 
 
@@ -59,6 +60,7 @@ TEST_F(AllocEngine4Test, simpleAlloc4) {
 
 
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
                                     false, true, "somehost.example.com.", false);
                                     false, true, "somehost.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
 
 
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
     // The new lease has been allocated, so the old lease should not exist.
     // The new lease has been allocated, so the old lease should not exist.
@@ -88,6 +90,7 @@ TEST_F(AllocEngine4Test, fakeAlloc4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, true,
                                     IOAddress("0.0.0.0"), false, true,
                                     "host.example.com.", true);
                                     "host.example.com.", true);
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
 
 
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
 
 
@@ -117,6 +120,7 @@ TEST_F(AllocEngine4Test, allocWithValidHint4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.105"), true, true,
                                     IOAddress("192.0.2.105"), true, true,
                                     "host.example.com.", false);
                                     "host.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
 
 
     // Check that we got a lease
     // Check that we got a lease
@@ -163,6 +167,7 @@ TEST_F(AllocEngine4Test, allocWithUsedHint4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.106"), false, false,
                                     IOAddress("192.0.2.106"), false, false,
                                     "", true);
                                     "", true);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
 
 
     // New lease has been allocated, so the old lease should not exist.
     // New lease has been allocated, so the old lease should not exist.
@@ -200,6 +205,7 @@ TEST_F(AllocEngine4Test, allocBogusHint4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("10.1.1.1"), false, false,
                                     IOAddress("10.1.1.1"), false, false,
                                     "", true);
                                     "", true);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
     // Check that we got a lease
     // Check that we got a lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -229,6 +235,7 @@ TEST_F(AllocEngine4Test, allocateLease4Nulls) {
     AllocEngine::ClientContext4 ctx1(Subnet4Ptr(), clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(Subnet4Ptr(), clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease = engine->allocateLease4(ctx1);
     Lease4Ptr lease = engine->allocateLease4(ctx1);
 
 
     EXPECT_FALSE(lease);
     EXPECT_FALSE(lease);
@@ -237,6 +244,7 @@ TEST_F(AllocEngine4Test, allocateLease4Nulls) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, HWAddrPtr(),
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, HWAddrPtr(),
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     lease = engine->allocateLease4(ctx2);
     lease = engine->allocateLease4(ctx2);
     EXPECT_FALSE(lease);
     EXPECT_FALSE(lease);
     EXPECT_FALSE(ctx2.old_lease_);
     EXPECT_FALSE(ctx2.old_lease_);
@@ -246,6 +254,7 @@ TEST_F(AllocEngine4Test, allocateLease4Nulls) {
     AllocEngine::ClientContext4 ctx3(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx3(subnet_, ClientIdPtr(), hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx3.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     lease = engine->allocateLease4(ctx3);
     lease = engine->allocateLease4(ctx3);
 
 
     // Check that we got a lease
     // Check that we got a lease
@@ -358,6 +367,7 @@ TEST_F(AllocEngine4Test, smallPool4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "host.example.com.", false);
                                     "host.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
 
 
     // Check that we got that single lease
     // Check that we got that single lease
@@ -415,6 +425,7 @@ TEST_F(AllocEngine4Test, outOfAddresses4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "host.example.com.", false);
                                     "host.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr lease2 = engine->allocateLease4(ctx);
     Lease4Ptr lease2 = engine->allocateLease4(ctx);
     EXPECT_FALSE(lease2);
     EXPECT_FALSE(lease2);
     EXPECT_FALSE(ctx.old_lease_);
     EXPECT_FALSE(ctx.old_lease_);
@@ -458,6 +469,7 @@ TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", true);
                                     "", true);
+    ctx1.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     lease = engine->allocateLease4(ctx1);
     lease = engine->allocateLease4(ctx1);
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -476,6 +488,7 @@ TEST_F(AllocEngine4Test, discoverReuseExpiredLease4) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress(addr), false, false,
                                     IOAddress(addr), false, false,
                                     "", true);
                                     "", true);
+    ctx2.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     lease = engine->allocateLease4(ctx2);
     lease = engine->allocateLease4(ctx2);
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -517,6 +530,7 @@ TEST_F(AllocEngine4Test, requestReuseExpiredLease4) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress(addr), false, false,
                                     IOAddress(addr), false, false,
                                     "host.example.com.", false);
                                     "host.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     lease = engine->allocateLease4(ctx);
     lease = engine->allocateLease4(ctx);
 
 
     // Check that he got that single lease
     // Check that he got that single lease
@@ -548,6 +562,7 @@ TEST_F(AllocEngine4Test, identifyClientLease) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress::IPV4_ZERO_ADDRESS(),
                                     IOAddress::IPV4_ZERO_ADDRESS(),
                                     false, false, "", true);
                                     false, false, "", true);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
 
 
     Lease4Ptr identified_lease = engine.allocateLease4(ctx);
     Lease4Ptr identified_lease = engine.allocateLease4(ctx);
     ASSERT_TRUE(identified_lease);
     ASSERT_TRUE(identified_lease);
@@ -627,6 +642,7 @@ TEST_F(AllocEngine4Test, requestOtherClientLease) {
     // First client requests the lease which belongs to the second client.
     // First client requests the lease which belongs to the second client.
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("192.0.2.102"),
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("192.0.2.102"),
                                     false, false, "", false);
                                     false, false, "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     Lease4Ptr new_lease = engine.allocateLease4(ctx);
     Lease4Ptr new_lease = engine.allocateLease4(ctx);
     // Allocation engine should return NULL.
     // Allocation engine should return NULL.
     ASSERT_FALSE(new_lease);
     ASSERT_FALSE(new_lease);
@@ -667,6 +683,7 @@ TEST_F(AllocEngine4Test, reservedAddressNoHint) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
 
 
@@ -704,6 +721,7 @@ TEST_F(AllocEngine4Test,reservedAddressNoHintFakeAllocation) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", true);
                                     "", true);
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
 
 
@@ -742,6 +760,7 @@ TEST_F(AllocEngine4Test, reservedAddressHint) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.234"), false, false,
                                     IOAddress("192.0.2.234"), false, false,
                                     "", false);
                                     "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr lease = engine.allocateLease4(ctx1);
     Lease4Ptr lease = engine.allocateLease4(ctx1);
 
 
@@ -755,6 +774,7 @@ TEST_F(AllocEngine4Test, reservedAddressHint) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.123"), false, false,
                                     IOAddress("192.0.2.123"), false, false,
                                     "", false);
                                     "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     lease = engine.allocateLease4(ctx2);
     lease = engine.allocateLease4(ctx2);
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -791,6 +811,7 @@ TEST_F(AllocEngine4Test, reservedAddressHintFakeAllocation) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.234"), false, false,
                                     IOAddress("192.0.2.234"), false, false,
                                     "", true);
                                     "", true);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
     Lease4Ptr lease = engine.allocateLease4(ctx);
 
 
@@ -837,6 +858,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLease) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.123"), false, false,
                                     IOAddress("192.0.2.123"), false, false,
                                     "", false);
                                     "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
 
 
@@ -885,6 +907,7 @@ TEST_F(AllocEngine4Test, reservedAddressHijacked) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.123"), false, false,
                                     IOAddress("192.0.2.123"), false, false,
                                     "", false);
                                     "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     // The lease is allocated to someone else, so the allocation should not
     // The lease is allocated to someone else, so the allocation should not
@@ -903,6 +926,7 @@ TEST_F(AllocEngine4Test, reservedAddressHijacked) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     ASSERT_FALSE(allocated_lease);
     ASSERT_FALSE(allocated_lease);
@@ -942,6 +966,7 @@ TEST_F(AllocEngine4Test, reservedAddressHijackedFakeAllocation) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.123"), false, false,
                                     IOAddress("192.0.2.123"), false, false,
                                     "", true);
                                     "", true);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
 
 
@@ -958,6 +983,7 @@ TEST_F(AllocEngine4Test, reservedAddressHijackedFakeAllocation) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", true);
                                     "", true);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
 
 
@@ -999,6 +1025,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseInvalidHint) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.102"), false, false,
                                     IOAddress("192.0.2.102"), false, false,
                                     "", false);
                                     "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     ASSERT_FALSE(allocated_lease);
     ASSERT_FALSE(allocated_lease);
@@ -1009,6 +1036,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseInvalidHint) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.101"), false, false,
                                     IOAddress("192.0.2.101"), false, false,
                                     "", false);
                                     "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     // The client has reservation so the server wants to allocate a
     // The client has reservation so the server wants to allocate a
@@ -1053,6 +1081,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseFakeAllocation) {
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.102"), false, false,
                                     IOAddress("192.0.2.102"), false, false,
                                     "", true);
                                     "", true);
+    ctx1.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
 
 
@@ -1072,6 +1101,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseFakeAllocation) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.101"), false, false,
                                     IOAddress("192.0.2.101"), false, false,
                                     "", true);
                                     "", true);
+    ctx2.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
 
 
@@ -1115,6 +1145,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseNoHint) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
 
 
@@ -1167,6 +1198,7 @@ TEST_F(AllocEngine4Test, reservedAddressExistingLeaseNoHintFakeAllocation) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"), false, false,
                                     IOAddress("0.0.0.0"), false, false,
                                     "", true);
                                     "", true);
+    ctx.query_.reset(new Pkt4(DHCPDISCOVER, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
 
 
@@ -1232,6 +1264,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr2_,
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr2_,
                                     IOAddress("192.0.2.101"), false, false,
                                     IOAddress("192.0.2.101"), false, false,
                                     "", false);
                                     "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr offered_lease = engine.allocateLease4(ctx1);
     Lease4Ptr offered_lease = engine.allocateLease4(ctx1);
     ASSERT_FALSE(offered_lease);
     ASSERT_FALSE(offered_lease);
@@ -1242,6 +1275,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.101"), false, false,
                                     IOAddress("192.0.2.101"), false, false,
                                     "", false);
                                     "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     ASSERT_FALSE(engine.allocateLease4(ctx2));
     ASSERT_FALSE(engine.allocateLease4(ctx2));
 
 
@@ -1253,6 +1287,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx3(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx3(subnet_, clientid_, hwaddr_,
                                     IOAddress("192.0.2.101"), false, false,
                                     IOAddress("192.0.2.101"), false, false,
                                     "", true);
                                     "", true);
+    ctx3.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx3);
     AllocEngine::findReservation(ctx3);
     offered_lease = engine.allocateLease4(ctx3);
     offered_lease = engine.allocateLease4(ctx3);
     ASSERT_TRUE(offered_lease);
     ASSERT_TRUE(offered_lease);
@@ -1264,6 +1299,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx4(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx4(subnet_, clientid_, hwaddr_,
                                     offered_lease->addr_, false, false,
                                     offered_lease->addr_, false, false,
                                     "", false);
                                     "", false);
+    ctx4.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx4);
     AllocEngine::findReservation(ctx4);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx4);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx4);
 
 
@@ -1275,6 +1311,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx5(subnet_, ClientIdPtr(), hwaddr2_,
     AllocEngine::ClientContext4 ctx5(subnet_, ClientIdPtr(), hwaddr2_,
                                      IOAddress("0.0.0.0"), false, false,
                                      IOAddress("0.0.0.0"), false, false,
                                     "", true);
                                     "", true);
+    ctx5.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx5);
     AllocEngine::findReservation(ctx5);
     offered_lease = engine.allocateLease4(ctx5);
     offered_lease = engine.allocateLease4(ctx5);
 
 
@@ -1285,6 +1322,7 @@ TEST_F(AllocEngine4Test, reservedAddressConflictResolution) {
     AllocEngine::ClientContext4 ctx6(subnet_, ClientIdPtr(), hwaddr2_,
     AllocEngine::ClientContext4 ctx6(subnet_, ClientIdPtr(), hwaddr2_,
                                      offered_lease->addr_, false, false,
                                      offered_lease->addr_, false, false,
                                     "", false);
                                     "", false);
+    ctx6.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     allocated_lease = engine.allocateLease4(ctx6);
     allocated_lease = engine.allocateLease4(ctx6);
 
 
     ASSERT_TRUE(allocated_lease);
     ASSERT_TRUE(allocated_lease);
@@ -1310,6 +1348,7 @@ TEST_F(AllocEngine4Test, reservedAddressVsDynamicPool) {
     AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
                                      IOAddress("0.0.0.0"), false, false,
                                      IOAddress("0.0.0.0"), false, false,
                                     "", false);
                                     "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
 
 
@@ -1338,6 +1377,7 @@ TEST_F(AllocEngine4Test, reservedAddressHintUsedByOtherClient) {
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
                                      IOAddress("192.0.2.100"), false, false,
                                      IOAddress("192.0.2.100"), false, false,
                                      "", false);
                                      "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
 
 
@@ -1349,6 +1389,7 @@ TEST_F(AllocEngine4Test, reservedAddressHintUsedByOtherClient) {
     AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
                                      IOAddress("192.0.2.100"), false, false,
                                      IOAddress("192.0.2.100"), false, false,
                                      "", true);
                                      "", true);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
 
 
@@ -1377,6 +1418,7 @@ TEST_F(AllocEngine4Test, reservedAddressShortPool) {
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx1(subnet_, ClientIdPtr(), hwaddr_,
                                      IOAddress("0.0.0.0"), false, false,
                                      IOAddress("0.0.0.0"), false, false,
                                      "", false);
                                      "", false);
+    ctx1.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx1);
     AllocEngine::findReservation(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx1);
 
 
@@ -1390,6 +1432,7 @@ TEST_F(AllocEngine4Test, reservedAddressShortPool) {
     AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx2(subnet_, ClientIdPtr(), hwaddr_,
                                      IOAddress("0.0.0.0"), false, false,
                                      IOAddress("0.0.0.0"), false, false,
                                      "", false);
                                      "", false);
+    ctx2.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx2);
     AllocEngine::findReservation(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
     allocated_lease = engine.allocateLease4(ctx2);
 
 
@@ -1416,6 +1459,7 @@ TEST_F(AllocEngine4Test, reservedHostname) {
     AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, ClientIdPtr(), hwaddr_,
                                     IOAddress("192.0.2.109"), false, false,
                                     IOAddress("192.0.2.109"), false, false,
                                     "foo.example.org", true);
                                     "foo.example.org", true);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     AllocEngine::findReservation(ctx);
     AllocEngine::findReservation(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     Lease4Ptr allocated_lease = engine.allocateLease4(ctx);
     ASSERT_TRUE(allocated_lease);
     ASSERT_TRUE(allocated_lease);

+ 21 - 0
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc

@@ -13,6 +13,8 @@
 // PERFORMANCE OF THIS SOFTWARE.
 // PERFORMANCE OF THIS SOFTWARE.
 
 
 #include <config.h>
 #include <config.h>
+#include <dhcp/pkt4.h>
+#include <dhcp/pkt6.h>
 #include <dhcpsrv/tests/alloc_engine_utils.h>
 #include <dhcpsrv/tests/alloc_engine_utils.h>
 #include <dhcpsrv/tests/test_utils.h>
 #include <dhcpsrv/tests/test_utils.h>
 
 
@@ -378,6 +380,7 @@ TEST_F(AllocEngine6Test, smallPool6) {
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA, fqdn_fwd_, fqdn_rev_,
                                     Lease::TYPE_NA, fqdn_fwd_, fqdn_rev_,
                                     hostname_, false);
                                     hostname_, false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 
 
     // Check that we got that single lease
     // Check that we got that single lease
@@ -432,6 +435,8 @@ TEST_F(AllocEngine6Test, outOfAddresses6) {
     Lease6Ptr lease2;
     Lease6Ptr lease2;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA, false, false, "", false);
                                     Lease::TYPE_NA, false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+
     EXPECT_NO_THROW(lease2 = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease2 = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_FALSE(lease2);
     EXPECT_FALSE(lease2);
 
 
@@ -467,6 +472,8 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
     // CASE 1: Asking for any address
     // CASE 1: Asking for any address
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
                                      Lease::TYPE_NA, fqdn_fwd_, fqdn_rev_, hostname_, true);
                                      Lease::TYPE_NA, fqdn_fwd_, fqdn_rev_, hostname_, true);
+    ctx1.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx1)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx1)));
     // Check that we got that single lease
     // Check that we got that single lease
     ASSERT_TRUE(lease);
     ASSERT_TRUE(lease);
@@ -478,6 +485,7 @@ TEST_F(AllocEngine6Test, solicitReuseExpiredLease6) {
     // CASE 2: Asking specifically for this address
     // CASE 2: Asking specifically for this address
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, addr, Lease::TYPE_NA,
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, addr, Lease::TYPE_NA,
                                      false, false, "", true);
                                      false, false, "", true);
+    ctx2.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx2)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx2)));
 
 
     // Check that we got that single lease
     // Check that we got that single lease
@@ -519,6 +527,7 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
     // A client comes along, asking specifically for this address
     // A client comes along, asking specifically for this address
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, addr, Lease::TYPE_NA,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, addr, Lease::TYPE_NA,
                                     false, false, "", false);
                                     false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 
 
     // Check that he got that single lease
     // Check that he got that single lease
@@ -968,6 +977,7 @@ TEST_F(AllocEngine6Test, reservedAddress) {
     for (int i = 0; i < 30; i++) {
     for (int i = 0; i < 30; i++) {
         AllocEngine::ClientContext6 ctx(subnet_, clients[i], iaid_, IOAddress("::"),
         AllocEngine::ClientContext6 ctx(subnet_, clients[i], iaid_, IOAddress("::"),
                                         Lease::TYPE_NA,  false, false, "", false);
                                         Lease::TYPE_NA,  false, false, "", false);
+        ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
         findReservation(engine, ctx);
         findReservation(engine, ctx);
         Lease6Collection leases = engine.allocateLeases6(ctx);
         Lease6Collection leases = engine.allocateLeases6(ctx);
         if (leases.empty()) {
         if (leases.empty()) {
@@ -991,6 +1001,8 @@ TEST_F(AllocEngine6Test, reservedAddress) {
     // address reserved, will get it (despite the pool being depleted).
     // address reserved, will get it (despite the pool being depleted).
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA,  false, false, "", false);
                                     Lease::TYPE_NA,  false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+
     findReservation(engine, ctx);
     findReservation(engine, ctx);
     Lease6Collection leases = engine.allocateLeases6(ctx);
     Lease6Collection leases = engine.allocateLeases6(ctx);
     ASSERT_EQ(1, leases.size());
     ASSERT_EQ(1, leases.size());
@@ -1004,6 +1016,7 @@ TEST_F(AllocEngine6Test, allocateLeasesInvalidData) {
     // That looks like a valid context.
     // That looks like a valid context.
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA,  false, false, "", false);
                                     Lease::TYPE_NA,  false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     Lease6Collection leases;
     Lease6Collection leases;
 
 
     // Let's break it!
     // Let's break it!
@@ -1098,6 +1111,7 @@ TEST_F(AllocEngine6Test, DISABLED_reserved2AddressesSolicit) {
 
 
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
                                     pool_->getType(), false, false, "", true);
                                     pool_->getType(), false, false, "", true);
+    ctx1.query_.reset(new Pkt6(DHCPV6_SOLICIT, 1234));
     Lease6Collection leases1;
     Lease6Collection leases1;
     findReservation(engine, ctx1);
     findReservation(engine, ctx1);
     EXPECT_NO_THROW(leases1 = engine.allocateLeases6(ctx1));
     EXPECT_NO_THROW(leases1 = engine.allocateLeases6(ctx1));
@@ -1108,6 +1122,7 @@ TEST_F(AllocEngine6Test, DISABLED_reserved2AddressesSolicit) {
     // the same address.
     // the same address.
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, IOAddress("::"),
                                     pool_->getType(), false, false, "", true);
                                     pool_->getType(), false, false, "", true);
+    ctx2.query_.reset(new Pkt6(DHCPV6_SOLICIT, 1234));
     Lease6Collection leases2;
     Lease6Collection leases2;
     findReservation(engine, ctx2);
     findReservation(engine, ctx2);
     EXPECT_NO_THROW(leases2 = engine.allocateLeases6(ctx2));
     EXPECT_NO_THROW(leases2 = engine.allocateLeases6(ctx2));
@@ -1118,6 +1133,7 @@ TEST_F(AllocEngine6Test, DISABLED_reserved2AddressesSolicit) {
     // different iaid. The second address should be assigned.
     // different iaid. The second address should be assigned.
     AllocEngine::ClientContext6 ctx3(subnet_, duid_, iaid_ + 1, IOAddress("::"),
     AllocEngine::ClientContext6 ctx3(subnet_, duid_, iaid_ + 1, IOAddress("::"),
                                     pool_->getType(), false, false, "", true);
                                     pool_->getType(), false, false, "", true);
+    ctx3.query_.reset(new Pkt6(DHCPV6_SOLICIT, 1234));
     Lease6Collection leases3;
     Lease6Collection leases3;
     findReservation(engine, ctx3);
     findReservation(engine, ctx3);
     EXPECT_NO_THROW(leases3 = engine.allocateLeases6(ctx3));
     EXPECT_NO_THROW(leases3 = engine.allocateLeases6(ctx3));
@@ -1142,6 +1158,7 @@ TEST_F(AllocEngine6Test, reserved2Addresses) {
 
 
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx1(subnet_, duid_, iaid_, IOAddress("::"),
                                     pool_->getType(), false, false, "", false);
                                     pool_->getType(), false, false, "", false);
+    ctx1.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     Lease6Collection leases1;
     Lease6Collection leases1;
     findReservation(engine, ctx1);
     findReservation(engine, ctx1);
     EXPECT_NO_THROW(leases1 = engine.allocateLeases6(ctx1));
     EXPECT_NO_THROW(leases1 = engine.allocateLeases6(ctx1));
@@ -1152,6 +1169,8 @@ TEST_F(AllocEngine6Test, reserved2Addresses) {
     // the same address.
     // the same address.
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx2(subnet_, duid_, iaid_, IOAddress("::"),
                                     pool_->getType(), false, false, "", false);
                                     pool_->getType(), false, false, "", false);
+    ctx2.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+
     Lease6Collection leases2;
     Lease6Collection leases2;
     findReservation(engine, ctx2);
     findReservation(engine, ctx2);
     EXPECT_NO_THROW(leases2 = engine.allocateLeases6(ctx2));
     EXPECT_NO_THROW(leases2 = engine.allocateLeases6(ctx2));
@@ -1162,6 +1181,8 @@ TEST_F(AllocEngine6Test, reserved2Addresses) {
     // different iaid. The second address should be assigned.
     // different iaid. The second address should be assigned.
     AllocEngine::ClientContext6 ctx3(subnet_, duid_, iaid_ + 1, IOAddress("::"),
     AllocEngine::ClientContext6 ctx3(subnet_, duid_, iaid_ + 1, IOAddress("::"),
                                     pool_->getType(), false, false, "", false);
                                     pool_->getType(), false, false, "", false);
+    ctx3.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+    
     Lease6Collection leases3;
     Lease6Collection leases3;
     findReservation(engine, ctx3);
     findReservation(engine, ctx3);
     EXPECT_NO_THROW(leases3 = engine.allocateLeases6(ctx3));
     EXPECT_NO_THROW(leases3 = engine.allocateLeases6(ctx3));

+ 4 - 0
src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc

@@ -157,6 +157,7 @@ TEST_F(HookAllocEngine6Test, lease6_select) {
     Lease6Ptr lease;
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA, false, false, "", false);
                                     Lease::TYPE_NA, false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     ctx.callout_handle_ = callout_handle;
     ctx.callout_handle_ = callout_handle;
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     // Check that we got a lease
     // Check that we got a lease
@@ -229,6 +230,7 @@ TEST_F(HookAllocEngine6Test, change_lease6_select) {
     Lease6Ptr lease;
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, IOAddress("::"),
                                     Lease::TYPE_NA, false, false, "", false);
                                     Lease::TYPE_NA, false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     ctx.callout_handle_ = callout_handle;
     ctx.callout_handle_ = callout_handle;
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     // Check that we got a lease
     // Check that we got a lease
@@ -386,6 +388,7 @@ TEST_F(HookAllocEngine4Test, lease4_select) {
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_,
                                     IOAddress("0.0.0.0"),
                                     IOAddress("0.0.0.0"),
                                     false, false, "", false);
                                     false, false, "", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     ctx.callout_handle_ = callout_handle;
     ctx.callout_handle_ = callout_handle;
 
 
     Lease4Ptr lease = engine->allocateLease4(ctx);
     Lease4Ptr lease = engine->allocateLease4(ctx);
@@ -454,6 +457,7 @@ TEST_F(HookAllocEngine4Test, change_lease4_select) {
 
 
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
     AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
                                     false, true, "somehost.example.com.", false);
                                     false, true, "somehost.example.com.", false);
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
     ctx.callout_handle_ = callout_handle;
     ctx.callout_handle_ = callout_handle;
 
 
     // Call allocateLease4. Callouts should be triggered here.
     // Call allocateLease4. Callouts should be triggered here.

+ 10 - 0
src/lib/dhcpsrv/tests/alloc_engine_utils.cc

@@ -17,6 +17,8 @@
 #include <dhcp/duid.h>
 #include <dhcp/duid.h>
 #include <dhcp/dhcp4.h>
 #include <dhcp/dhcp4.h>
 #include <dhcp/dhcp6.h>
 #include <dhcp/dhcp6.h>
+#include <dhcp/pkt4.h>
+#include <dhcp/pkt6.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/lease_mgr.h>
 #include <dhcpsrv/lease_mgr.h>
 #include <dhcpsrv/memfile_lease_mgr.h>
 #include <dhcpsrv/memfile_lease_mgr.h>
@@ -122,6 +124,7 @@ AllocEngine6Test::allocateTest(AllocEngine& engine, const Pool6Ptr& pool,
 
 
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type,
                                     false, false, "", fake);
                                     false, false, "", fake);
+    ctx.query_.reset(new Pkt6(fake ? DHCPV6_SOLICIT : DHCPV6_REQUEST, 1234));
 
 
     Lease6Collection leases;
     Lease6Collection leases;
 
 
@@ -181,6 +184,8 @@ AllocEngine6Test::simpleAlloc6Test(const Pool6Ptr& pool, const IOAddress& hint,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type,
                                     false, false, "", fake);
                                     false, false, "", fake);
     ctx.hwaddr_ = hwaddr_;
     ctx.hwaddr_ = hwaddr_;
+    ctx.query_.reset(new Pkt6(fake ? DHCPV6_SOLICIT : DHCPV6_REQUEST, 1234));
+
     findReservation(*engine, ctx);
     findReservation(*engine, ctx);
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 
 
@@ -229,6 +234,7 @@ AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool,
     ctx.hints_ = hints;
     ctx.hints_ = hints;
     ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 123));
     ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 123));
     ctx.allow_new_leases_in_renewals_ = allow_new_leases_in_renewal;
     ctx.allow_new_leases_in_renewals_ = allow_new_leases_in_renewal;
+    ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 1234));
 
 
     findReservation(engine, ctx);
     findReservation(engine, ctx);
     Lease6Collection leases = engine.renewLeases6(ctx);
     Lease6Collection leases = engine.renewLeases6(ctx);
@@ -278,6 +284,7 @@ AllocEngine6Test::allocWithUsedHintTest(Lease::Type type, IOAddress used_addr,
     Lease6Ptr lease;
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, requested, type,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, requested, type,
                                     false, false, "", false);
                                     false, false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 
 
     // Check that we got a lease
     // Check that we got a lease
@@ -314,6 +321,8 @@ AllocEngine6Test::allocBogusHint6(Lease::Type type, asiolink::IOAddress hint,
     Lease6Ptr lease;
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type, false,
     AllocEngine::ClientContext6 ctx(subnet_, duid_, iaid_, hint, type, false,
                                     false, "", false);
                                     false, "", false);
+    ctx.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
+
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx)));
 
 
     // Check that we got a lease
     // Check that we got a lease
@@ -378,6 +387,7 @@ AllocEngine4Test::AllocEngine4Test() {
     ctx_.clientid_ = clientid_;
     ctx_.clientid_ = clientid_;
     ctx_.hwaddr_ = hwaddr_;
     ctx_.hwaddr_ = hwaddr_;
     ctx_.callout_handle_ = HooksManager::createCalloutHandle();
     ctx_.callout_handle_ = HooksManager::createCalloutHandle();
+    ctx_.query_.reset(new Pkt4(DHCPREQUEST, 1234));
 }
 }
 
 
 }; // namespace test
 }; // namespace test