Browse Source

[master] Merge branch 'trac3852'

Marcin Siodelski 10 years ago
parent
commit
923928774f

+ 14 - 0
doc/guide/logging.xml

@@ -180,6 +180,13 @@
             provided.</simpara>
             provided.</simpara>
           </listitem>
           </listitem>
           <listitem>
           <listitem>
+            <simpara><command>kea-dhcp4.alloc-engine</command> - this is the
+            logger used by the lease allocation engine, which is responsible
+            for managing leases in the lease database, i.e. create, modify
+            and remove DHCPv4 leases as a result of processing messages from
+            the clients.</simpara>
+          </listitem>
+          <listitem>
             <simpara><command>kea-dhcp4.bad-packets</command> - this is the
             <simpara><command>kea-dhcp4.bad-packets</command> - this is the
             logger used by the DHCPv4 server deamon for logging inbound client
             logger used by the DHCPv4 server deamon for logging inbound client
             packets that were dropped or to which the server responded with a
             packets that were dropped or to which the server responded with a
@@ -273,6 +280,13 @@
             used DHCPv6 server deamon to log basic operations.</simpara>
             used DHCPv6 server deamon to log basic operations.</simpara>
           </listitem>
           </listitem>
           <listitem>
           <listitem>
+            <simpara><command>kea-dhcp6.alloc-engine</command> - this is the
+            logger used by the lease allocation engine, which is responsible
+            for managing leases in the lease database, i.e. create, modify
+            and remove DHCPv6 leases as a result of processing messages from
+            the clients.</simpara>
+          </listitem>
+          <listitem>
             <simpara><command>kea-dhcp6.dhcpsrv</command> - this is a base
             <simpara><command>kea-dhcp6.dhcpsrv</command> - this is a base
             logger for the libdhcpsrv library.</simpara>
             logger for the libdhcpsrv library.</simpara>
           </listitem>
           </listitem>

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

@@ -113,6 +113,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

@@ -290,6 +290,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);
@@ -1413,6 +1414,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);
 
 
@@ -1573,6 +1575,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);
 
 

+ 2 - 0
src/lib/dhcpsrv/.gitignore

@@ -1,3 +1,5 @@
+/alloc_engine_messages.cc
+/alloc_engine_messages.h
 /dhcpsrv_messages.cc
 /dhcpsrv_messages.cc
 /dhcpsrv_messages.h
 /dhcpsrv_messages.h
 /hosts_messages.cc
 /hosts_messages.cc

+ 22 - 12
src/lib/dhcpsrv/Makefile.am

@@ -35,21 +35,26 @@ EXTRA_DIST += parsers/host_reservation_parser.h
 EXTRA_DIST += parsers/host_reservations_list_parser.h
 EXTRA_DIST += parsers/host_reservations_list_parser.h
 
 
 # Define rule to build logging source files from message file
 # Define rule to build logging source files from message file
-dhcpsrv_messages.h dhcpsrv_messages.cc hosts_messages.h hosts_messages.cc: s-messages
+alloc_engine_messages.h alloc_engine_messages.cc dhcpsrv_messages.h \
+dhcpsrv_messages.cc hosts_messages.h hosts_messages.cc: s-messages
 
 
-s-messages: dhcpsrv_messages.mes hosts_messages.mes
+s-messages: alloc_engine_messages.mes dhcpsrv_messages.mes hosts_messages.mes
+	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/alloc_engine_messages.mes
+	touch $@
 	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/dhcpsrv_messages.mes
 	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/dhcpsrv_messages.mes
 	touch $@
 	touch $@
 	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/hosts_messages.mes
 	$(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/lib/dhcpsrv/hosts_messages.mes
 	touch $@
 	touch $@
 
 
-# Tell Automake that the {dhcpsrv,hosts}_messages.{cc,h} source files are created
-# in the build process, so it must create these before doing anything else.
-# Although they are a dependency of the library (so will be created from the message
-# file anyway), there is no guarantee as to exactly _when_ in the build they will be
-# created.  As the .h file is included in other sources file (so must be
-# present when they are compiled), the safest option is to create it first.
-BUILT_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
+# Tell Automake that the {alloc_engine,dhcpsrv,hosts}_messages.{cc,h} source files
+# are created in the build process, so it must create these before doing anything
+# else. Although they are a dependency of the library (so will be created from the
+# message file anyway), there is no guarantee as to exactly _when_ in the build
+# they will be created.  As the .h file is included in other sources file (so
+# must be present when they are compiled), the safest option is to create it
+# first.
+BUILT_SOURCES = alloc_engine_messages.h alloc_engine_messages.cc
+BUILT_SOURCES += dhcpsrv_messages.h dhcpsrv_messages.cc
 BUILT_SOURCES += hosts_messages.h hosts_messages.cc
 BUILT_SOURCES += hosts_messages.h hosts_messages.cc
 
 
 # Some versions of GCC warn about some versions of Boost regarding
 # Some versions of GCC warn about some versions of Boost regarding
@@ -59,7 +64,9 @@ BUILT_SOURCES += hosts_messages.h hosts_messages.cc
 AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
 AM_CXXFLAGS += $(WARNING_NO_MISSING_FIELD_INITIALIZERS_CFLAG)
 
 
 # Make sure the generated files are deleted in a "clean" operation
 # Make sure the generated files are deleted in a "clean" operation
-CLEANFILES = *.gcno *.gcda dhcpsrv_messages.h dhcpsrv_messages.cc
+CLEANFILES = *.gcno *.gcda
+CLEANFILES += alloc_engine_messages.h alloc_engine_messages.cc
+CLEANFILES += dhcpsrv_messages.h dhcpsrv_messages.cc
 CLEANFILES += hosts_messages.h hosts_messages.cc s-messages
 CLEANFILES += hosts_messages.h hosts_messages.cc s-messages
 # Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests.
 # Remove CSV files created by the CSVLeaseFile6 and CSVLeaseFile4 unit tests.
 CLEANFILES += *.csv
 CLEANFILES += *.csv
@@ -68,6 +75,7 @@ lib_LTLIBRARIES = libkea-dhcpsrv.la
 libkea_dhcpsrv_la_SOURCES  =
 libkea_dhcpsrv_la_SOURCES  =
 libkea_dhcpsrv_la_SOURCES += addr_utilities.cc addr_utilities.h
 libkea_dhcpsrv_la_SOURCES += addr_utilities.cc addr_utilities.h
 libkea_dhcpsrv_la_SOURCES += alloc_engine.cc alloc_engine.h
 libkea_dhcpsrv_la_SOURCES += alloc_engine.cc alloc_engine.h
+libkea_dhcpsrv_la_SOURCES += alloc_engine_log.cc alloc_engine_log.h
 libkea_dhcpsrv_la_SOURCES += base_host_data_source.h
 libkea_dhcpsrv_la_SOURCES += base_host_data_source.h
 libkea_dhcpsrv_la_SOURCES += callout_handle_store.h
 libkea_dhcpsrv_la_SOURCES += callout_handle_store.h
 libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
 libkea_dhcpsrv_la_SOURCES += cfg_hosts.cc cfg_hosts.h
@@ -128,8 +136,9 @@ libkea_dhcpsrv_la_SOURCES += parsers/host_reservations_list_parser.h
 libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.cc
 libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.cc
 libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h
 libkea_dhcpsrv_la_SOURCES += parsers/ifaces_config_parser.h
 
 
-
-nodist_libkea_dhcpsrv_la_SOURCES = dhcpsrv_messages.h dhcpsrv_messages.cc
+nodist_libkea_dhcpsrv_la_SOURCES = alloc_engine__messages.h
+nodist_libkea_dhcpsrv_la_SOURCES += alloc_engine_messages.cc
+nodist_libkea_dhcpsrv_la_SOURCES += dhcpsrv_messages.h dhcpsrv_messages.cc
 nodist_libkea_dhcpsrv_la_SOURCES += hosts_messages.h hosts_messages.cc
 nodist_libkea_dhcpsrv_la_SOURCES += hosts_messages.h hosts_messages.cc
 
 
 libkea_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS)
 libkea_dhcpsrv_la_CXXFLAGS = $(AM_CXXFLAGS)
@@ -159,6 +168,7 @@ libkea_dhcpsrv_la_CXXFLAGS += -Wno-unused-parameter
 endif
 endif
 
 
 # The message file should be in the distribution
 # The message file should be in the distribution
+EXTRA_DIST += alloc_engine_messages.mes
 EXTRA_DIST += dhcpsrv_messages.mes
 EXTRA_DIST += dhcpsrv_messages.mes
 EXTRA_DIST += hosts_messages.mes
 EXTRA_DIST += hosts_messages.mes
 
 

+ 174 - 25
src/lib/dhcpsrv/alloc_engine.cc

@@ -15,6 +15,7 @@
 #include <config.h>
 #include <config.h>
 
 
 #include <dhcpsrv/alloc_engine.h>
 #include <dhcpsrv/alloc_engine.h>
+#include <dhcpsrv/alloc_engine_log.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/host.h>
 #include <dhcpsrv/host.h>
@@ -380,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.
@@ -405,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);
@@ -423,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);
@@ -477,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()) {
@@ -484,12 +501,16 @@ AllocEngine::allocateLeases6(ClientContext6& ctx) {
         }
         }
 
 
         // Unable to allocate an address, return an empty lease.
         // Unable to allocate an address, return an empty lease.
-        LOG_WARN(dhcpsrv_logger, DHCPSRV_ADDRESS6_ALLOC_FAIL).arg(attempts_);
+        LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_V6_ALLOC_FAIL)
+            .arg(ctx.query_->getLabel())
+            .arg(attempts_);
 
 
     } 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_ADDRESS6_ALLOC_ERROR).arg(e.what());
+        LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_V6_ALLOC_ERROR)
+            .arg(ctx.query_->getLabel())
+            .arg(e.what());
     }
     }
 
 
     return (Lease6Collection());
     return (Lease6Collection());
@@ -510,7 +531,7 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
 
 
     Lease6Collection leases;
     Lease6Collection leases;
 
 
-    IOAddress hint("::");
+    IOAddress hint = IOAddress::IPV6_ZERO_ADDRESS();
     if (!ctx.hints_.empty()) {
     if (!ctx.hints_.empty()) {
         /// @todo: We support only one hint for now
         /// @todo: We support only one hint for now
         hint = ctx.hints_[0].first;
         hint = ctx.hints_[0].first;
@@ -554,7 +575,13 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
                     collection.push_back(lease);
                     collection.push_back(lease);
                     return (collection);
                     return (collection);
                 }
                 }
+            } else {
+                LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                          ALLOC_ENGINE_V6_HINT_RESERVED)
+                    .arg(ctx.query_->getLabel())
+                    .arg(hint.toText());
             }
             }
+
         } else {
         } else {
 
 
             // If the lease is expired, we may likely reuse it, but...
             // If the lease is expired, we may likely reuse it, but...
@@ -579,6 +606,12 @@ AllocEngine::allocateUnreservedLeases6(ClientContext6& ctx) {
                     /// @todo: We support only one lease per ia for now
                     /// @todo: We support only one lease per ia for now
                     leases.push_back(lease);
                     leases.push_back(lease);
                     return (leases);
                     return (leases);
+
+                } else {
+                    LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                              ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED)
+                        .arg(ctx.query_->getLabel())
+                        .arg(hint.toText());
                 }
                 }
             }
             }
         }
         }
@@ -667,6 +700,9 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
 
 
     // If there are no reservations or the reservation is v4, there's nothing to do.
     // If there are no reservations or the reservation is v4, there's nothing to do.
     if (!ctx.host_ || !ctx.host_->hasIPv6Reservation()) {
     if (!ctx.host_ || !ctx.host_->hasIPv6Reservation()) {
+        LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                  ALLOC_ENGINE_V6_ALLOC_NO_V6_HR)
+            .arg(ctx.query_->getLabel());
         return;
         return;
     }
     }
 
 
@@ -675,12 +711,6 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
 
 
     // Get the IPv6 reservations of specified type.
     // Get the IPv6 reservations of specified type.
     const IPv6ResrvRange& reservs = ctx.host_->getIPv6Reservations(type);
     const IPv6ResrvRange& reservs = ctx.host_->getIPv6Reservations(type);
-
-    if (std::distance(reservs.first, reservs.second) == 0) {
-        // No reservations? We're done here.
-        return;
-    }
-
     for (IPv6ResrvIterator resv = reservs.first; resv != reservs.second; ++resv) {
     for (IPv6ResrvIterator resv = reservs.first; resv != reservs.second; ++resv) {
         // We do have a reservation for addr.
         // We do have a reservation for addr.
         IOAddress addr = resv->second.getPrefix();
         IOAddress addr = resv->second.getPrefix();
@@ -692,6 +722,11 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
 
 
             // Ok, we already have a lease for this reservation and it's usable
             // Ok, we already have a lease for this reservation and it's usable
             if (((*l)->addr_ == addr) && (*l)->valid_lft_ != 0) {
             if (((*l)->addr_ == addr) && (*l)->valid_lft_ != 0) {
+                LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
+                          ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS)
+                    .arg(ctx.query_->getLabel())
+                    .arg((*l)->typeToText((*l)->type_))
+                    .arg((*l)->addr_.toText());
                 return;
                 return;
             }
             }
         }
         }
@@ -706,12 +741,14 @@ AllocEngine::allocateReservedLeases6(ClientContext6& ctx, Lease6Collection& exis
             existing_leases.push_back(lease);
             existing_leases.push_back(lease);
 
 
             if (ctx.type_ == Lease::TYPE_NA) {
             if (ctx.type_ == Lease::TYPE_NA) {
-                LOG_INFO(dhcpsrv_logger, DHCPSRV_HR_RESERVED_ADDR_GRANTED)
-                    .arg(addr.toText()).arg(ctx.duid_->toText());
+                LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_V6_HR_ADDR_GRANTED)
+                    .arg(addr.toText())
+                    .arg(ctx.query_->getLabel());
             } else {
             } else {
-                LOG_INFO(dhcpsrv_logger, DHCPSRV_HR_RESERVED_PREFIX_GRANTED)
-                    .arg(addr.toText()).arg(static_cast<int>(prefix_len))
-                    .arg(ctx.duid_->toText());
+                LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_V6_HR_PREFIX_GRANTED)
+                    .arg(addr.toText())
+                    .arg(static_cast<int>(prefix_len))
+                    .arg(ctx.query_->getLabel());
             }
             }
 
 
             // We found a lease for this client and this IA. Let's return.
             // We found a lease for this client and this IA. Let's return.
@@ -759,11 +796,11 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
         // Ok, we have a problem. This host has a lease that is reserved
         // Ok, we have a problem. This host has a lease that is reserved
         // for someone else. We need to recover from this.
         // for someone else. We need to recover from this.
         if (ctx.type_ == Lease::TYPE_NA) {
         if (ctx.type_ == Lease::TYPE_NA) {
-            LOG_INFO(dhcpsrv_logger, DHCPSRV_HR_REVOKED_ADDR6_LEASE)
+            LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_V6_REVOKED_ADDR_LEASE)
                 .arg((*candidate)->addr_.toText()).arg(ctx.duid_->toText())
                 .arg((*candidate)->addr_.toText()).arg(ctx.duid_->toText())
                 .arg(host->getIdentifierAsText());
                 .arg(host->getIdentifierAsText());
         } else {
         } else {
-            LOG_INFO(dhcpsrv_logger, DHCPSRV_HR_REVOKED_PREFIX6_LEASE)
+            LOG_INFO(alloc_engine_logger, ALLOC_ENGINE_V6_REVOKED_PREFIX_LEASE)
                 .arg((*candidate)->addr_.toText())
                 .arg((*candidate)->addr_.toText())
                 .arg(static_cast<int>((*candidate)->prefixlen_))
                 .arg(static_cast<int>((*candidate)->prefixlen_))
                 .arg(ctx.duid_->toText())
                 .arg(ctx.duid_->toText())
@@ -880,8 +917,10 @@ AllocEngine::reuseExpiredLease(Lease6Ptr& expired, ClientContext6& ctx,
     expired->fqdn_rev_ = ctx.rev_dns_update_;
     expired->fqdn_rev_ = ctx.rev_dns_update_;
     expired->prefixlen_ = prefix_len;
     expired->prefixlen_ = prefix_len;
 
 
-    /// @todo: log here that the lease was reused (there's ticket #2524 for
-    /// logging in libdhcpsrv)
+    LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
+              ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA)
+        .arg(ctx.query_->getLabel())
+        .arg(expired->toText());
 
 
     // Let's execute all callouts registered for lease6_select
     // Let's execute all callouts registered for lease6_select
     if (ctx.callout_handle_ &&
     if (ctx.callout_handle_ &&
@@ -1023,12 +1062,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);
 
 
@@ -1044,11 +1092,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);
         }
         }
 
 
@@ -1057,7 +1115,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());
@@ -1084,6 +1144,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());
+
     // Keep the old data in case the callout tells us to skip update.
     // Keep the old data in case the callout tells us to skip update.
     Lease6 old_data = *lease;
     Lease6 old_data = *lease;
 
 
@@ -1097,6 +1162,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 ?
@@ -1277,7 +1347,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,
@@ -1316,12 +1386,16 @@ AllocEngine::allocateLease4(ClientContext4& ctx) {
         new_lease = ctx.fake_allocation_ ? discoverLease4(ctx) : requestLease4(ctx);
         new_lease = ctx.fake_allocation_ ? discoverLease4(ctx) : requestLease4(ctx);
         if (!new_lease) {
         if (!new_lease) {
             // Unable to allocate an address, return an empty lease.
             // Unable to allocate an address, return an empty lease.
-            LOG_WARN(dhcpsrv_logger, DHCPSRV_ADDRESS4_ALLOC_FAIL).arg(attempts_);
+            LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_V4_ALLOC_FAIL)
+                .arg(ctx.query_->getLabel())
+                .arg(attempts_);
         }
         }
 
 
     } 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_ADDRESS4_ALLOC_ERROR).arg(e.what());
+        LOG_ERROR(alloc_engine_logger, ALLOC_ENGINE_V4_ALLOC_ERROR)
+            .arg(ctx.query_->getLabel())
+            .arg(e.what());
     }
     }
 
 
     return (new_lease);
     return (new_lease);
@@ -1362,6 +1436,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
@@ -1375,7 +1455,8 @@ AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
             // allocate in the DHCPREQUEST time.
             // allocate in the DHCPREQUEST time.
             new_lease = allocateOrReuseLease4(ctx.host_->getIPv4Reservation(), ctx);
             new_lease = allocateOrReuseLease4(ctx.host_->getIPv4Reservation(), ctx);
             if (!new_lease) {
             if (!new_lease) {
-                LOG_WARN(dhcpsrv_logger, DHCPSRV_DISCOVER_ADDRESS_CONFLICT)
+                LOG_WARN(alloc_engine_logger, ALLOC_ENGINE_V4_DISCOVER_ADDRESS_CONFLICT)
+                    .arg(ctx.query_->getLabel())
                     .arg(ctx.host_->getIPv4Reservation().toText())
                     .arg(ctx.host_->getIPv4Reservation().toText())
                     .arg(ctx.conflicting_lease_ ? ctx.conflicting_lease_->toText() :
                     .arg(ctx.conflicting_lease_ ? ctx.conflicting_lease_->toText() :
                          "(no lease info)");
                          "(no lease info)");
@@ -1399,6 +1480,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);
     }
     }
 
 
@@ -1413,6 +1498,11 @@ 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_REQUESTED_LEASE)
+            .arg(ctx.requested_address_.toText())
+            .arg(ctx.query_->getLabel());
+
         new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
         new_lease = allocateOrReuseLease4(ctx.requested_address_, ctx);
     }
     }
 
 
@@ -1420,6 +1510,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);
     }
     }
 
 
@@ -1455,6 +1550,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());
         }
         }
 
 
@@ -1464,6 +1565,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()) {
@@ -1476,6 +1582,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());
         }
         }
 
 
@@ -1491,6 +1603,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());
             }
             }
         }
         }
@@ -1501,6 +1620,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());
         }
         }
     }
     }
@@ -1514,6 +1639,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));
         }
         }
     }
     }
@@ -1525,6 +1656,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,
@@ -1534,6 +1671,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.
@@ -1545,6 +1686,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_);
     }
     }
 
 
@@ -1725,8 +1872,10 @@ AllocEngine::reuseExpiredLease4(Lease4Ptr& expired,
     updateLease4Information(expired, ctx);
     updateLease4Information(expired, ctx);
     expired->fixed_ = false;
     expired->fixed_ = false;
 
 
-    /// @todo: log here that the lease was reused (there's ticket #2524 for
-    /// logging in libdhcpsrv)
+    LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA,
+              ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA)
+        .arg(ctx.query_->getLabel())
+        .arg(expired->toText());
 
 
     // Let's execute all callouts registered for lease4_select
     // Let's execute all callouts registered for lease4_select
     if (ctx.callout_handle_ &&  HooksManager::getHooksManager()
     if (ctx.callout_handle_ &&  HooksManager::getHooksManager()

+ 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();
 
 

+ 26 - 0
src/lib/dhcpsrv/alloc_engine_log.cc

@@ -0,0 +1,26 @@
+// Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+/// @file Defines the logger used by the @c isc::dhcp::HostMgr
+
+#include "dhcpsrv/alloc_engine_log.h"
+
+namespace isc {
+namespace dhcp {
+
+isc::log::Logger alloc_engine_logger("alloc-engine");
+
+} // namespace dhcp
+} // namespace isc
+

+ 58 - 0
src/lib/dhcpsrv/alloc_engine_log.h

@@ -0,0 +1,58 @@
+// Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef ALLOC_ENGINE_LOG_H
+#define ALLOC_ENGINE_LOG_H
+
+#include <dhcpsrv/alloc_engine_messages.h>
+#include <log/macros.h>
+
+namespace isc {
+namespace dhcp {
+
+///@{
+/// \brief Logging levels for the @c AllocEngine.
+///
+/// Defines the levels used to output debug messages from the @c AllocEngine.
+
+/// @brief Traces normal operations
+const int ALLOC_ENGINE_DBG_TRACE = DBGLVL_TRACE_BASIC;
+
+/// @brief Records the results of various operations.
+///
+/// Messages logged at this level will typically contain summary of the
+/// data retrieved.
+const int ALLOC_ENGINE_DBG_RESULTS = DBGLVL_TRACE_BASIC_DATA;
+
+/// @brief Record detailed traces
+///
+/// Messages logged at this level will log detailed tracing information.
+const int ALLOC_ENGINE_DBG_TRACE_DETAIL = DBGLVL_TRACE_DETAIL;
+
+/// @brief Records detailed results of various operations.
+///
+/// Messages logged at this level will contain detailed results.
+const int ALLOC_ENGINE_DBG_TRACE_DETAIL_DATA = DBGLVL_TRACE_DETAIL_DATA;
+
+///@}
+
+/// @brief Logger for the @c AllocEngine..
+///
+/// Define the logger used to log messages in @c AllocEngine.
+extern isc::log::Logger alloc_engine_logger;
+
+} // namespace dhcp
+} // namespace isc
+
+#endif // ALLOC_ENGINE_LOG_H

+ 291 - 0
src/lib/dhcpsrv/alloc_engine_messages.mes

@@ -0,0 +1,291 @@
+# Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+$NAMESPACE isc::dhcp
+
+% ALLOC_ENGINE_V4_ALLOC_ERROR %1: error during attempt to allocate an IPv4 address: %2
+An error occurred during an attempt to allocate an IPv4 address, the
+reason for the failure being contained in the message.  The server will
+return a message to the client refusing a lease. The first argument
+includes the client identification information.
+
+% ALLOC_ENGINE_V4_ALLOC_FAIL %1: failed to allocate an IPv4 address after %2 attempt(s)
+The DHCP allocation engine gave up trying to allocate an IPv4 address
+after the specified number of attempts.  This probably means that the
+address pool from which the allocation is being attempted is either
+empty, or very nearly empty.  As a result, the client will have been
+refused a lease. The first argument includes the client identification
+information.
+
+This message may indicate that your address pool is too small for the
+number of clients you are trying to service and should be expanded.
+Alternatively, if the you know that the number of concurrently active
+clients is less than the addresses you have available, you may want to
+consider reducing the lease lifetime.  In this way, addresses allocated
+to clients that are no longer active on the network will become available
+sooner.
+
+% ALLOC_ENGINE_V4_DISCOVER_ADDRESS_CONFLICT %1: conflicting reservation for address %2 with existing lease %3
+This warning message is issued when the DHCP server finds that the
+address reserved for the client can't be offered because this address
+is currently allocated to another client. The server will try to allocate
+a different address to the client to use until the conflict is resolved.
+The first argument includes the client identification information.
+
+% ALLOC_ENGINE_V4_DISCOVER_HR client %1 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 allocation engine will try to offer existing lease to the client %1
+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 allocation engine will try to offer new lease to the client %1
+This message is issued when the allocation engine will try to
+offer a 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 a hint, or the address in
+the hint is in use.
+
+% ALLOC_ENGINE_V4_OFFER_REQUESTED_LEASE allocation engine will try to offer requested lease %1 to the client %2
+This message is issued when the allocation engine will try to
+offer the lease specified in the hint. This situation may occur
+when: (a) client doesn't have any reservations, (b) client has
+reservation but the reserved address is leased to another client.
+
+% ALLOC_ENGINE_V4_REQUEST_ADDRESS_RESERVED %1: requested address %2 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. The first argument
+includes the client identification information.
+
+% 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 an expired) address which has been
+requested by the client. The first argument includes the
+client identification information.
+
+% 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 whose lifetime can be
+extended, and which can be returned to the client.
+The first argument includes the client identification information.
+
+% 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. The first argument
+includes the client identification information.
+
+% ALLOC_ENGINE_V4_REQUEST_INVALID client %1 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 this when the reserved address is in use by
+another client. However, the allocation engine has 
+determined that the reserved address is available and the
+client should request the reserved address.
+
+% ALLOC_ENGINE_V4_REQUEST_OUT_OF_POOL client %1, which doesn't have reservation, requested address out 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 client %1 hasn't specified an address - picking available address from the pool
+This message is logged when the client hasn't specified any
+preferred address (the client should always do it, but Kea 
+tries to be forgiving). The allocation engine will try to pick an available
+address from the dynamic pool and allocate it 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 one.
+
+% ALLOC_ENGINE_V4_REQUEST_USE_HR client %1 hasn't requested specific address, using reserved address %2
+This message is issued when the client is not requesting any specific
+address but the allocation engine has determined that there is a
+reservation for this client. The allocation engine will try to
+allocate the reserved address.
+
+% ALLOC_ENGINE_V4_REUSE_EXPIRED_LEASE_DATA %1: reusing expired lease, updated lease information: %2
+This message is logged when the allocation engine is reusing
+an existing lease. The details of the updated lease are
+printed. The first argument includes the client identification
+information.
+
+% ALLOC_ENGINE_V6_ALLOC_ERROR %1: error during attempt to allocate an IPv6 address: %2
+An error occurred during an attempt to allocate an IPv6 address, the
+reason for the failure being contained in the message.  The server will
+return a message to the client refusing a lease. The first argument
+includes the client identification information.
+
+% ALLOC_ENGINE_V6_ALLOC_FAIL %1: failed to allocate an IPv6 address after %2 attempt(s)
+The DHCP allocation engine gave up trying to allocate an IPv6 address
+after the specified number of attempts.  This probably means that the
+address pool from which the allocation is being attempted is either
+empty, or very nearly empty.  As a result, the client will have been
+refused a lease. The first argument includes the client identification
+information.
+
+This message may indicate that your address pool is too small for the
+number of clients you are trying to service and should be expanded.
+Alternatively, if the you know that the number of concurrently active
+clients is less than the addresses you have available, you may want to
+consider reducing the lease lifetime.  In this way, addresses allocated
+to clients that are no longer active on the network will become available
+available sooner.
+
+% ALLOC_ENGINE_V6_ALLOC_HR_LEASE_EXISTS %1: lease type %2 for reserved address/prefix %3 already exists
+This debug message is issued when the allocation engine determines that
+the lease for the IPv6 address or prefix has already been allocated
+for the client and the client can continue using it. The first argument
+includes the client identification information.
+
+% ALLOC_ENGINE_V6_ALLOC_LEASES_HR leases and static reservations found for client %1
+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 engine 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 no leases found but reservations exist for client %1
+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_NO_V6_HR %1: unable to allocate reserved leases - no IPv6 reservations
+This message is logged when the allocation engine determines that the
+client has no IPv6 reservations and thus the allocation engine will have
+to try to allocate allocating leases from the dynamic pool or stop
+the allocation process if none can be allocated. The first argument
+includes the client identification information.
+
+% ALLOC_ENGINE_V6_ALLOC_LEASES_NO_HR no reservations found but leases exist for client %1
+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 no static reservations available - trying to dynamically allocate leases for client %1
+This debug message is issued when the allocation engine will attempt
+to allocate leases from the dynamic pools.  This may be due to one of
+(a) there are no reservations for this client, (b) there are
+reservations for the client but they are not usable because the addresses
+are in use by another client or (c) we had a reserved lease but that
+has now been allocated to another client.
+
+% ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED allocate new (unreserved) leases for the renewing client %1
+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. The first argument includes the
+client identification information.
+
+% 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). The first argument
+includes the client identification information.
+
+% 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. The first argument
+includes the client identification information.
+
+% 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. The first argument includes the client identification
+information.
+
+% ALLOC_ENGINE_V6_EXPIRED_HINT_RESERVED %1: expired lease for the client's hint %2 is reserved for another client
+This message is logged when the allocation engine finds that the
+expired lease for the client's hint can't be reused because it
+is reserved for another client. The first argument includes the
+client identification information.
+
+% ALLOC_ENGINE_V6_HINT_RESERVED %1: lease for the client's hint %2 is reserved for another client
+This message is logged when the allocation engine cannot allocate
+the lease using the client's hint because the lease for this hint
+is reserved for another client. The first argument includes the
+client identification information.
+
+% ALLOC_ENGINE_V6_HR_ADDR_GRANTED reserved address %1 was was assigned to client %2
+This informational message signals that the specified client was assigned the address
+reserved for it.
+
+% ALLOC_ENGINE_V6_HR_PREFIX_GRANTED reserved prefix %1/%2 was was assigned to client %3
+This informational message signals that the specified client was assigned the prefix
+reserved for it.
+
+% ALLOC_ENGINE_V6_RENEW_HR allocating leases reserved for the client %1 as a result of Renew
+This debug message is issued when the allocation engine tries 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 that 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
+requesting their renewal. The first argument includes the client
+identification information.
+
+% ALLOC_ENGINE_V6_RENEW_REMOVE_UNRESERVED dynamically allocating leases for the renewing client %1
+This debug message is issued as 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.
+
+% ALLOC_ENGINE_V6_REUSE_EXPIRED_LEASE_DATA %1: reusing expired lease, updated lease information: %2
+This message is logged when the allocation engine is reusing
+an existing lease. The details of the updated lease are
+printed. The first argument includes the client identification
+information.
+
+% ALLOC_ENGINE_V6_REVOKED_ADDR_LEASE address %1 was revoked from client %2 as it is reserved for client %3
+This informational message is an indication that the specified IPv6
+address was used by client A but it is now reserved for client B. Client
+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
+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
+recover from this situation, but clients will change their addresses.
+
+% ALLOC_ENGINE_V6_REVOKED_PREFIX_LEASE Prefix %1/%2 was revoked from client %3 as it is reserved for client %4
+This informational message is an indication that the specified IPv6
+prefix was used by client A but it is now reserved for client B. Client
+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
+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
+recover from this situation, but clients will change their prefixes.

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

@@ -14,46 +14,6 @@
 
 
 $NAMESPACE isc::dhcp
 $NAMESPACE isc::dhcp
 
 
-% DHCPSRV_ADDRESS4_ALLOC_ERROR error during attempt to allocate an IPv4 address: %1
-An error occurred during an attempt to allocate an IPv4 address, the
-reason for the failure being contained in the message.  The server will
-return a message to the client refusing a lease.
-
-% DHCPSRV_ADDRESS4_ALLOC_FAIL failed to allocate an IPv4 address after %1 attempt(s)
-The DHCP allocation engine gave up trying to allocate an IPv4 address
-after the specified number of attempts.  This probably means that the
-address pool from which the allocation is being attempted is either
-empty, or very nearly empty.  As a result, the client will have been
-refused a lease.
-
-This message may indicate that your address pool is too small for the
-number of clients you are trying to service and should be expanded.
-Alternatively, if the you know that the number of concurrently active
-clients is less than the addresses you have available, you may want to
-consider reducing the lease lifetime.  In this way, addresses allocated
-to clients that are no longer active on the network will become available
-available sooner.
-
-% DHCPSRV_ADDRESS6_ALLOC_ERROR error during attempt to allocate an IPv6 address: %1
-An error occurred during an attempt to allocate an IPv6 address, the
-reason for the failure being contained in the message.  The server will
-return a message to the client refusing a lease.
-
-% DHCPSRV_ADDRESS6_ALLOC_FAIL failed to allocate an IPv6 address after %1 attempt(s)
-The DHCP allocation engine gave up trying to allocate an IPv6 address
-after the specified number of attempts.  This probably means that the
-address pool from which the allocation is being attempted is either
-empty, or very nearly empty.  As a result, the client will have been
-refused a lease.
-
-This message may indicate that your address pool is too small for the
-number of clients you are trying to service and should be expanded.
-Alternatively, if the you know that the number of concurrently active
-clients is less than the addresses you have available, you may want to
-consider reducing the lease lifetime.  In this way, addresses allocated
-to clients that are no longer active on the network will become available
-available sooner.
-
 % DHCPSRV_CFGMGR_ADD_IFACE listening on interface %1
 % DHCPSRV_CFGMGR_ADD_IFACE listening on interface %1
 An info message issued when a new interface is being added to the collection of
 An info message issued when a new interface is being added to the collection of
 interfaces on which the server listens to DHCP messages.
 interfaces on which the server listens to DHCP messages.
@@ -216,12 +176,6 @@ have been experienced.  Any such errors should have preceding entries in the
 log with details.  No further attempts to communicate with kea-dhcp-ddns will
 log with details.  No further attempts to communicate with kea-dhcp-ddns will
 be made without intervention.
 be made without intervention.
 
 
-% DHCPSRV_DISCOVER_ADDRESS_CONFLICT conflicting reservation for address %1 with existing lease %2
-This warning message is issued when the DHCP server finds that the
-address reserved for the client can't be offered because this address
-is currently allocated to another client. The server will try to allocate
-a different address to the client to use until the conflict is resolved.
-
 % DHCPSRV_HOOK_LEASE4_RENEW_SKIP DHCPv4 lease was not renewed because a callout set the skip flag.
 % DHCPSRV_HOOK_LEASE4_RENEW_SKIP DHCPv4 lease was not renewed because a callout set the skip flag.
 This debug message is printed when a callout installed on lease4_renew
 This debug message is printed when a callout installed on lease4_renew
 hook point set the skip flag. For this particular hook point, the setting
 hook point set the skip flag. For this particular hook point, the setting
@@ -248,32 +202,6 @@ hook point sets the skip flag. It means that the server was told that
 no lease6 should be assigned. The server will not put that lease in its
 no lease6 should be assigned. The server will not put that lease in its
 database and the client will get a NoAddrsAvail for that IA_NA option.
 database and the client will get a NoAddrsAvail for that IA_NA option.
 
 
-% DHCPSRV_HR_RESERVED_ADDR_GRANTED reserved address %1 was was assigned to client (duid=%2)
-This informational message signals that the specified client was assigned the address
-reserved for it.
-
-% DHCPSRV_HR_RESERVED_PREFIX_GRANTED reserved prefix %1/%2 was was assigned to client (duid=%3)
-This informational message signals that the specified client was assigned the prefix
-reserved for it.
-
-% DHCPSRV_HR_REVOKED_ADDR6_LEASE address %1 was revoked from client %2 as it is reserved for client %3
-This informational message is an indication that the specified IPv6
-address was used by client A but it is now reserved for client B. Client
-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
-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
-recover from this situation, but clients will change their addresses.
-
-% DHCPSRV_HR_REVOKED_PREFIX6_LEASE Prefix %1/%2 was revoked from client %3 as it is reserved for client %4
-This informational message is an indication that the specified IPv6
-prefix was used by client A but it is now reserved for client B. Client
-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
-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
-recover from this situation, but clients will change their prefixes.
-
 % DHCPSRV_INVALID_ACCESS invalid database access string: %1
 % DHCPSRV_INVALID_ACCESS invalid database access string: %1
 This is logged when an attempt has been made to parse a database access string
 This is logged when an attempt has been made to parse a database access string
 and the attempt ended in error.  The access string in question - which
 and the attempt ended in error.  The access string in question - which
@@ -599,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);

+ 23 - 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>
 
 
@@ -123,12 +125,14 @@ TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
     Lease6Ptr lease;
     Lease6Ptr lease;
     AllocEngine::ClientContext6 ctx1(Subnet6Ptr(), duid_, iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx1(Subnet6Ptr(), duid_, iaid_, IOAddress("::"),
                                      Lease::TYPE_NA, false, false, "", false);
                                      Lease::TYPE_NA, false, false, "", false);
+    ctx1.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx1)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx1)));
     ASSERT_FALSE(lease);
     ASSERT_FALSE(lease);
 
 
     // Allocations without DUID are not allowed either
     // Allocations without DUID are not allowed either
     AllocEngine::ClientContext6 ctx2(subnet_, DuidPtr(), iaid_, IOAddress("::"),
     AllocEngine::ClientContext6 ctx2(subnet_, DuidPtr(), iaid_, IOAddress("::"),
                                      Lease::TYPE_NA, false, false, "", false);
                                      Lease::TYPE_NA, false, false, "", false);
+    ctx2.query_.reset(new Pkt6(DHCPV6_REQUEST, 1234));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx2)));
     EXPECT_NO_THROW(lease = expectOneLease(engine->allocateLeases6(ctx2)));
     ASSERT_FALSE(lease);
     ASSERT_FALSE(lease);
 }
 }
@@ -378,6 +382,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 +437,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 +474,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 +487,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 +529,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 +979,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 +1003,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 +1018,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 +1113,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 +1124,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 +1135,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 +1160,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 +1171,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 +1183,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