return (ctx.host_ && !ctx.host_->getIPv4Reservation().isV4Zero());
}
+/// @brief Check if there is a lease for the client which message is processed.
+///
+/// This function searches the lease database to find existing lease for the client.
+/// It finds the lease using the client's HW address first. If the lease exists and
+/// appears to belong to the client the lease is returned. Otherwise, the function
+/// will search for the lease using the client identifier (if supplied). If the
+/// lease exists and appears to belong to the client, it is returned.
+///
+/// This function also identifies the conflicts between existing leases and the
+/// lease to be allocated for the client, when the client is using a HW address
+/// or client identifier which is already in use by the client having a lease in
+/// the database. If the client uses an identifier which is already used by another
+/// client and no other unique identifier which could be used to identify the client's
+/// lease this function signals the conflict by returning 'true'.
+///
+/// @param ctx Client context.
+/// @param [out] client_lease Client's lease found in the database.
+///
+/// @return true if there is a conflict of identifiers (HW address or client id)
+/// between the client which message is being processed and the client which has
+/// a lease in the database. When the value 'true' is returned, the caller should
+/// cease the lease allocation for the client.
+bool matchClientLease(const AllocEngine::ClientContext4& ctx, Lease4Ptr& client_lease) {
+ // Obtain the sole instance of the LeaseMgr.
+ LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
+
+ // The server should hand out existing lease to the client, so we have to check
+ // if there is one. First, try to use the client's HW address.
+ client_lease = lease_mgr.getLease4(*ctx.hwaddr_, ctx.subnet_->getID());
+ // If there is no lease for this HW address or the lease doesn't seem to be ours,
+ // we will have to use the client identifier. Note that in some situations two
+ // clients may use the same HW address so even if we find the lease for the HW
+ // address it doesn't mean it is ours, because client identifier may not match.
+ if (ctx.clientid_ && ((!client_lease) || (client_lease && !ctx.myLease(*client_lease)))) {
+ // Check if the lease is in conflict with the lease that we want to allocate.
+ // If the lease is in conflict because of using overlapping HW address or
+ // client identifier, we can't allocate the lease for this client.
+ if (client_lease && ctx.isInConflict(*client_lease)) {
+ return (true);
+ }
+ // There is no lease or the lease we found is not conflicting with the lease
+ // which we have found for the HW address, so there is still a chance that
+ // we will allocate the lease. Check if there is a lease using the client
+ // identifier.
+ client_lease = lease_mgr.getLease4(*ctx.clientid_, ctx.subnet_->getID());
+ }
+
+ // Check if the lease we have found belongs to us.
+ if (client_lease && !ctx.myLease(*client_lease)) {
+ // If the lease doesn't belong to us, check if we can add new lease for
+ // the client which message we're processing, or its identifiers are
+ // in conflict with this lease.
+ if (ctx.isInConflict(*client_lease)) {
+ return (true);
+ }
+ // If there is no conflict we can proceed and try to find the appropriate
+ // lease but we don't use the one we found, because it is assigned to
+ // someone else. Reset the pointer to indicate that we're not
+ // renewing this lease.
+ client_lease.reset();
+ }
+
+ return (false);
+}
+
} // end of anonymous namespace
namespace isc {
Lease4Ptr
AllocEngine::discoverLease4(AllocEngine::ClientContext4& ctx) {
- // Obtain the sole instance of the LeaseMgr.
- LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-
- // The server should hand out existing lease to the client, so we have to check
- // if there is one. First, try to use the client's HW address.
- Lease4Ptr client_lease = lease_mgr.getLease4(*ctx.hwaddr_, ctx.subnet_->getID());
- // If there is no lease for this HW address or the lease doesn't seem to be ours,
- // we will have to use the client identifier. Note that in some situations two
- // clients may use the same HW address so even if we find the lease for the HW
- // address it doesn't mean it is ours, because client identifier may not match.
- if (ctx.clientid_ && ((!client_lease) || (client_lease && !ctx.myLease(*client_lease)))) {
- // Check if the lease is in conflict with the lease that we want to allocate.
- // If the lease is in conflict because of using overlapping HW address or
- // client identifier, we can't allocate the lease for this client.
- if (client_lease && ctx.isInConflict(*client_lease)) {
- return (Lease4Ptr());
- }
- // There is no lease or the lease we found is not conflicting with the lease
- // which we have found for the HW address, so there is still a chance that
- // we will allocate the lease. Check if there is a lease using the client
- // identifier.
- client_lease = lease_mgr.getLease4(*ctx.clientid_, ctx.subnet_->getID());
- }
-
- // Check if the lease we have found belongs to us.
- if (client_lease && !ctx.myLease(*client_lease)) {
- // If the lease doesn't belong to us, check if we can add new lease for
- // the client which message we're processing, or its identifiers are
- // in conflict with this lease.
- if (ctx.isInConflict(*client_lease)) {
- return (Lease4Ptr());
- }
- // If there is no conflict we can proceed and try to find the appropriate
- // lease but we don't use the one we found, because it is assigned to
- // someone else. Reset the pointer to indicate that we're not
- // renewing this lease.
- client_lease.reset();
+ // Find an existing lease for this client. This function will return true
+ // if there is a conflict with existing lease and the allocation should
+ // not be continued.
+ Lease4Ptr client_lease;
+ bool conflict = matchClientLease(ctx, client_lease);
+ if (conflict) {
+ return (Lease4Ptr());
}
// new_lease will hold the pointer to the lease that we will offer to the
Lease4Ptr
AllocEngine::requestLease4(AllocEngine::ClientContext4& ctx) {
- // Obtain the sole instance of the LeaseMgr.
- LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-
- // The server should hand out existing lease to the client, so we have to check
- // if there is one. First, try to use the client's HW address.
- Lease4Ptr client_lease = lease_mgr.getLease4(*ctx.hwaddr_, ctx.subnet_->getID());
- // If there is no lease for this HW address or the lease doesn't seem to be ours,
- // we will have to use the client identifier. Note that in some situations two
- // clients may use the same HW address so even if we find the lease for the HW
- // address it doesn't mean it is ours, because client identifier may not match.
- if (ctx.clientid_ && ((!client_lease) || (client_lease && !ctx.myLease(*client_lease)))) {
- // Check if the lease is in conflict with the lease that we want to allocate.
- // If the lease is in conflict because of using overlapping HW address or
- // client identifier, we can't allocate the lease for this client.
- if (client_lease && ctx.isInConflict(*client_lease)) {
- return (Lease4Ptr());
- }
- // There is no lease or the lease we found is not conflicting with the lease
- // which we have found for the HW address, so there is still a chance that
- // we will allocate the lease. Check if there is a lease using the client
- // identifier.
- client_lease = lease_mgr.getLease4(*ctx.clientid_, ctx.subnet_->getID());
+ // Find an existing lease for this client. This function will return true
+ // if there is a conflict with existing lease and the allocation should
+ // not be continued.
+ Lease4Ptr client_lease;
+ bool conflict = matchClientLease(ctx, client_lease);
+ if (conflict) {
+ return (Lease4Ptr());
}
- // Check if the lease we have found belongs to us.
- if (client_lease && !ctx.myLease(*client_lease)) {
- // If the lease doesn't belong to us, check if we can add new lease for
- // the client which message we're processing, or its identifiers are
- // in conflict with this lease.
- if (ctx.isInConflict(*client_lease)) {
- return (Lease4Ptr());
- }
- // If there is no conflict we can proceed and try to find the appropriate
- // lease but we don't use the one we found, because it is assigned to
- // someone else. Reset the pointer to indicate that we're not
- // renewing this lease.
- client_lease.reset();
- }
+ // Obtain the sole instance of the LeaseMgr.
+ LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
// When the client sends the DHCPREQUEST, it should always specify the
// address which it is requesting or renewing. That is, the client should