@@ -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