Skip to content

Commit 1586ae9

Browse files
authored
[DhcpServer] Fix lease IP management (#1428)
1 parent c60bb67 commit 1586ae9

File tree

1 file changed

+44
-27
lines changed

1 file changed

+44
-27
lines changed

devices/DhcpServer/DhcpServer.cs

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -167,22 +167,24 @@ public bool Start(IPAddress address, IPAddress mask, ushort timeToLeave = 1200)
167167
return true;
168168
}
169169

170+
private readonly object _dhcpListLock = new object();
171+
170172
private void CheckAndCleanList(object state)
171173
{
172-
ArrayList toRemove = new ArrayList();
173-
for (int i = 0; i < _dhcpLastRequest.Count; i++)
174+
lock (_dhcpListLock)
174175
{
175-
if ((DateTime)_dhcpLastRequest[i] < DateTime.UtcNow)
176+
// Remove items in reverse order to maintain correct indices
177+
for (int i = _dhcpLastRequest.Count - 1; i >= 0; i--)
176178
{
177-
toRemove.Add(i);
178-
}
179-
}
179+
if ((DateTime)_dhcpLastRequest[i] < DateTime.UtcNow.AddSeconds(-_timeToLeave))
180+
{
181+
_dhcpIpList.RemoveAt(i);
182+
_dhcpHardwareAddressList.RemoveAt(i);
183+
_dhcpLastRequest.RemoveAt(i);
180184

181-
foreach (int val in toRemove)
182-
{
183-
_dhcpIpList.RemoveAt(val);
184-
_dhcpHardwareAddressList.RemoveAt(val);
185-
_dhcpLastRequest.RemoveAt(val);
185+
Debug.WriteLine($"Removing expired lease for IP {(IPAddress)_dhcpIpList[i]}");
186+
}
187+
}
186188
}
187189
}
188190

@@ -289,28 +291,43 @@ private void RunServer()
289291
Debug.WriteLine($"Received REQUEST with ciaddr, client is RENEWING or REBINDING");
290292

291293
// Find the requested address in the list
292-
int inc;
293-
for (inc = 0; inc < _dhcpIpList.Count; inc++)
294+
lock (_dhcpListLock)
294295
{
295-
if (((IPAddress)_dhcpIpList[inc]).ToString() == dhcpReq.RequestedIpAddress.ToString())
296+
// Find the requested address in the list
297+
int inc = -1;
298+
for (int i = 0; i < _dhcpIpList.Count; i++)
296299
{
297-
break;
300+
if (((IPAddress)_dhcpIpList[i]).ToString() == dhcpReq.RequestedIpAddress.ToString())
301+
{
302+
inc = i;
303+
break;
304+
}
298305
}
299-
}
300306

301-
// Check if the hardware address is the same
302-
if ((string)_dhcpHardwareAddressList[inc] == dhcpReq.ClientHardwareAddressAsString)
303-
{
304-
_dhcpLastRequest[inc] = DateTime.UtcNow;
305-
}
306-
else
307-
{
308-
// In this case make a Nack
309-
_sender.Send(MessageBuilder.CreateNak(dhcpReq, _ipAddress).GetBytes());
310-
break;
307+
// Verify we found the IP and the hardware address matches
308+
if (inc >= 0 && inc < _dhcpHardwareAddressList.Count)
309+
{
310+
if ((string)_dhcpHardwareAddressList[inc] == dhcpReq.ClientHardwareAddressAsString)
311+
{
312+
_dhcpLastRequest[inc] = DateTime.UtcNow;
313+
_sender.Send(MessageBuilder.CreateAck(dhcpReq, _ipAddress, dhcpReq.RequestedIpAddress, _mask, _options).GetBytes());
314+
}
315+
else
316+
{
317+
// Hardware address mismatch - send NAK
318+
_sender.Send(MessageBuilder.CreateNak(dhcpReq, _ipAddress).GetBytes());
319+
}
320+
}
321+
else
322+
{
323+
// IP not found in our list - send NAK
324+
Debug.WriteLine($"Received RENEW/REBIND for unknown IP {dhcpReq.RequestedIpAddress}");
325+
326+
_sender.Send(MessageBuilder.CreateNak(dhcpReq, _ipAddress).GetBytes());
327+
}
311328
}
312329

313-
_sender.Send(MessageBuilder.CreateAck(dhcpReq, _ipAddress, dhcpReq.RequestedIpAddress, _mask, _options).GetBytes());
330+
break;
314331
}
315332

316333
}

0 commit comments

Comments
 (0)