From e27bd27d31e039003176920e3ca2a188af77344c Mon Sep 17 00:00:00 2001 From: Cory Charlton <10094287+CoryCharlton@users.noreply.github.com> Date: Thu, 9 Jul 2026 10:15:06 -0700 Subject: [PATCH] dhcp: allow reserved leases outside scope pool range but within subnet Reserved DHCP leases whose IP is outside the scope's [startingAddress, endingAddress] pool range but still inside the scope's subnet were rejected on add and, when added via the API back door, failed unicast renewal. - Scope: validate reserved-lease addresses by subnet membership (IsAddressInNetwork) instead of pool range (IsAddressInRange), in both the ReservedLeases setter and TryAddReservedLease so the console form and API agree. Wrong-subnet addresses are still rejected. - DhcpServer.FindScope: in the no-relay unicast (RENEW/REBIND) branch, match the scope by the client's reserved lease (keyed on MAC) before the pool-range check, mirroring the broadcast and relay branches. Previously an out-of-pool ciaddr matched no scope, so the REQUEST was silently dropped and the client lost its lease at T1. --- DnsServerCore/Dhcp/DhcpServer.cs | 9 ++++++++- DnsServerCore/Dhcp/Scope.cs | 7 +++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/DnsServerCore/Dhcp/DhcpServer.cs b/DnsServerCore/Dhcp/DhcpServer.cs index f7806d22b..4ad42b5c0 100644 --- a/DnsServerCore/Dhcp/DhcpServer.cs +++ b/DnsServerCore/Dhcp/DhcpServer.cs @@ -655,7 +655,14 @@ private Scope FindScope(DhcpMessage request, IPAddress remoteAddress, IPPacketIn { Scope scope = entry.Value; - if (scope.Enabled && scope.IsAddressInRange(request.ClientIpAddress)) + if (!scope.Enabled) + continue; + + Lease reservedLease = scope.GetReservedLease(request); + if ((reservedLease is not null) && reservedLease.Address.Equals(request.ClientIpAddress)) + return scope; //ciaddr is this client's reserved address (may be out of pool range) + + if (scope.IsAddressInRange(request.ClientIpAddress)) return scope; } diff --git a/DnsServerCore/Dhcp/Scope.cs b/DnsServerCore/Dhcp/Scope.cs index 4486dd566..4240c23f8 100644 --- a/DnsServerCore/Dhcp/Scope.cs +++ b/DnsServerCore/Dhcp/Scope.cs @@ -1477,6 +1477,9 @@ public void ChangeNetwork(IPAddress startingAddress, IPAddress endingAddress, IP public bool TryAddReservedLease(Lease reservedLease) { + if (!IsAddressInNetwork(reservedLease.Address)) + throw new ArgumentOutOfRangeException(nameof(reservedLease), "Reserved address must be within the scope's subnet."); + if (_reservedLeases.TryAdd(reservedLease.ClientIdentifier, reservedLease)) { _dhcpServer.AddDnsEntries(this, reservedLease); @@ -2175,8 +2178,8 @@ public IReadOnlyCollection ReservedLeases { foreach (Lease reservedLease in value) { - if (!IsAddressInRange(reservedLease.Address)) - throw new ArgumentOutOfRangeException(nameof(ReservedLeases), "Reserved address must be in scope range."); + if (!IsAddressInNetwork(reservedLease.Address)) + throw new ArgumentOutOfRangeException(nameof(ReservedLeases), "Reserved address must be within the scope's subnet."); } //remove DNS entries for reserved leases being removed or has updated domain name