Skip to content

Commit 3ce934c

Browse files
BornToBeRootclaude
andcommitted
Fix: IP Scanner: Error reading the neighbor table ended the scan (R15)
An exception of GetIpNetTable2 (Win32Exception of NeighborTable.GetTable) was not caught in GetNeighborEntryAsync. ARP / NDP is on by default and every local host reads the table before its probes, so an IP helper error aborted the whole scan. The error is logged once per scan and an empty snapshot is stored (no entry: hosts are only found by their probes, no MAC address from the table); the table is read again on the next miss. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent df47765 commit 3ce934c

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

‎Source/NETworkManager.Models/Network/IPScanner.cs‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Net.Sockets;
88
using System.Threading;
99
using System.Threading.Tasks;
10+
using log4net;
1011
using NETworkManager.Models.Lookup;
1112
using NETworkManager.Utilities;
1213

@@ -20,6 +21,8 @@ public sealed class IPScanner(IPScannerOptions options)
2021
{
2122
#region Variables
2223

24+
private static readonly ILog Log = LogManager.GetLogger(typeof(IPScanner));
25+
2326
/// <summary>
2427
/// Time between the start of two hosts during the ramp-up, see <see cref="StartScheduler" />. With the
2528
/// default settings the first 128 hosts are started within ~1.3 s instead of at the same moment (~11 connection
@@ -56,6 +59,9 @@ private sealed record NeighborTableSnapshot(Dictionary<IPAddress, NeighborInfo>
5659
private readonly SemaphoreSlim _neighborTableSemaphore = new(1, 1);
5760
private volatile NeighborTableSnapshot _neighborTable = new([], DateTime.MinValue);
5861

62+
// The neighbor table could not be read (logged once per scan), only changed while holding the semaphore
63+
private bool _neighborTableReadFailed;
64+
5965
private readonly SemaphoreSlim _neighborVerificationSemaphore =
6066
new(MaxConcurrentNeighborVerifications, MaxConcurrentNeighborVerifications);
6167

@@ -758,7 +764,27 @@ private async Task<NeighborInfo> GetNeighborEntryAsync(IPAddress ipAddress, Date
758764
// Timestamp before reading the table, so entries created while reading are covered by the next read
759765
var timestamp = DateTime.UtcNow;
760766

761-
_neighborTable = new NeighborTableSnapshot(NeighborTable.GetNeighborMap(), timestamp);
767+
Dictionary<IPAddress, NeighborInfo> entries;
768+
769+
try
770+
{
771+
entries = NeighborTable.GetNeighborMap();
772+
}
773+
catch (Exception ex)
774+
{
775+
// E.g. an error of the IP helper API: no entry instead of ending the scan (hosts are only found by their
776+
// probes and get no MAC address from the table), read again on the next miss
777+
if (!_neighborTableReadFailed)
778+
{
779+
_neighborTableReadFailed = true;
780+
781+
Log.Error("GetNeighborEntryAsync - Could not read the neighbor table (ARP / NDP).", ex);
782+
}
783+
784+
entries = [];
785+
}
786+
787+
_neighborTable = new NeighborTableSnapshot(entries, timestamp);
762788

763789
return _neighborTable.Entries.GetValueOrDefault(ipAddress);
764790
}

0 commit comments

Comments
 (0)