Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/GlobalAssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

[assembly: AssemblyVersion("2026.7.12.0")]
[assembly: AssemblyFileVersion("2026.7.12.0")]
[assembly: AssemblyVersion("2026.8.5.0")]
[assembly: AssemblyFileVersion("2026.8.5.0")]
34 changes: 0 additions & 34 deletions Source/NETworkManager.Localization/Resources/Strings.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 0 additions & 15 deletions Source/NETworkManager.Localization/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -3353,21 +3353,6 @@ If the option is disabled again, the values are no longer modified. However, the
<data name="PingStatus" xml:space="preserve">
<value>Ping status</value>
</data>
<data name="ThreadPoolAdditionalMinThreads" xml:space="preserve">
<value>ThreadPool additional min. threads</value>
</data>
<data name="HelpMessage_ThreadPoolAdditionalMinThreads" xml:space="preserve">
<value>This setting specifies the minimum number of threads that will be created from the application's ThreadPool on demand. This can improve the performance for example of the IP scanner or port scanner.

The value is added to the default min. threads (number of CPU threads). The value 0 leaves the default settings. If the value is higher than the default max. threads of the ThreadPool, this value is used.

If the value is too high, performance problems may occur.

Changes to this value will take effect after the application is restarted. Whether the value was set successfully can be seen in the log file under %LocalAppData%\NETworkManager\NETworkManager.log</value>
</data>
<data name="MaxThreadsOnlyGoToSettingsGeneralGeneral" xml:space="preserve">
<value>These settings only change the maximum number of concurrently executed threads per host/port scan. Go to Settings &gt; General &gt; General to adjust the (min) threads of the application.</value>
</data>
<data name="PortStatus" xml:space="preserve">
<value>Port status</value>
</data>
Expand Down
88 changes: 38 additions & 50 deletions Source/NETworkManager.Models/Network/HostRangeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,14 @@ public static IEnumerable<string> CreateListFromInput(string hosts)
.ToArray();
}

public static Task<(List<(IPAddress ipAddress, string hostname)> hosts, List<string> hostnamesNotResolved)>
public static async Task<(List<(IPAddress ipAddress, string hostname)> hosts, List<string> hostnamesNotResolved)>
ResolveAsync(IEnumerable<string> hosts, bool dnsResolveHostnamePreferIPv4, CancellationToken cancellationToken)
{
return Task.Run(() => Resolve(hosts, dnsResolveHostnamePreferIPv4, cancellationToken), cancellationToken);
}

private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string> hostnamesNotResolved) Resolve(
IEnumerable<string> hosts, bool dnsResolveHostnamePreferIPv4, CancellationToken cancellationToken)
{
var hostsBag = new ConcurrentBag<(IPAddress ipAddress, string hostname)>();
var hostnamesNotResovledBag = new ConcurrentBag<string>();

Parallel.ForEach(hosts, new ParallelOptions { CancellationToken = cancellationToken }, host =>
await Parallel.ForEachAsync(hosts, new ParallelOptions { CancellationToken = cancellationToken },
async (host, ct) =>
{
switch (host)
{
Expand All @@ -62,7 +57,7 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>
Parallel.For(IPv4Address.ToInt32(network.Network), IPv4Address.ToInt32(network.Broadcast) + 1,
(i, state) =>
{
if (cancellationToken.IsCancellationRequested)
if (ct.IsCancellationRequested)
state.Break();

hostsBag.Add((IPv4Address.FromInt32(i), string.Empty));
Expand All @@ -77,7 +72,7 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>
Parallel.For(IPv4Address.ToInt32(IPAddress.Parse(range[0])),
IPv4Address.ToInt32(IPAddress.Parse(range[1])) + 1, (i, state) =>
{
if (cancellationToken.IsCancellationRequested)
if (ct.IsCancellationRequested)
state.Break();

hostsBag.Add((IPv4Address.FromInt32(i), string.Empty));
Expand Down Expand Up @@ -107,7 +102,7 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>
Parallel.For(int.Parse(rangeNumbers[0]), int.Parse(rangeNumbers[1]) + 1,
(i, state) =>
{
if (cancellationToken.IsCancellationRequested)
if (ct.IsCancellationRequested)
state.Break();

innerList.Add(i);
Expand All @@ -124,18 +119,18 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>
}

// Build the new ipv4
Parallel.ForEach(list[0], new ParallelOptions { CancellationToken = cancellationToken },
Parallel.ForEach(list[0], new ParallelOptions { CancellationToken = ct },
i =>
{
Parallel.ForEach(list[1], new ParallelOptions { CancellationToken = cancellationToken },
Parallel.ForEach(list[1], new ParallelOptions { CancellationToken = ct },
j =>
{
Parallel.ForEach(list[2],
new ParallelOptions { CancellationToken = cancellationToken },
new ParallelOptions { CancellationToken = ct },
k =>
{
Parallel.ForEach(list[3],
new ParallelOptions { CancellationToken = cancellationToken },
new ParallelOptions { CancellationToken = ct },
h =>
{
hostsBag.Add((IPAddress.Parse($"{i}.{j}.{k}.{h}"), string.Empty));
Expand All @@ -148,17 +143,13 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>

// example.com
case var _ when RegexHelper.HostnameOrDomainRegex().IsMatch(host):
using (var dnsResolverTask =
DNSClientHelper.ResolveAorAaaaAsync(host, dnsResolveHostnamePreferIPv4))
{
// Wait for task inside a Parallel.Foreach
dnsResolverTask.Wait(cancellationToken);
var dnsResult = await DNSClientHelper.ResolveAorAaaaAsync(host, dnsResolveHostnamePreferIPv4)
.WaitAsync(ct).ConfigureAwait(false);

if (!dnsResolverTask.Result.HasError)
hostsBag.Add((IPAddress.Parse($"{dnsResolverTask.Result.Value}"), host));
else
hostnamesNotResovledBag.Add(host);
}
if (!dnsResult.HasError)
hostsBag.Add((IPAddress.Parse($"{dnsResult.Value}"), host));
else
hostnamesNotResovledBag.Add(host);

break;

Expand All @@ -168,42 +159,39 @@ private static (List<(IPAddress ipAddress, string hostname)> hosts, List<string>
var hostAndSubnet = host.Split('/');

// Only support IPv4
using (var dnsResolverTask = DNSClientHelper.ResolveAorAaaaAsync(hostAndSubnet[0], true))
{
// Wait for task inside a Parallel.Foreach
dnsResolverTask.Wait(cancellationToken);
var dnsResultWithSubnet = await DNSClientHelper.ResolveAorAaaaAsync(hostAndSubnet[0], true)
.WaitAsync(ct).ConfigureAwait(false);

if (!dnsResolverTask.Result.HasError)
if (!dnsResultWithSubnet.HasError)
{
// Only support IPv4 for ranges for now
if (dnsResultWithSubnet.Value.AddressFamily == AddressFamily.InterNetwork)
{
// Only support IPv4 for ranges for now
if (dnsResolverTask.Result.Value.AddressFamily == AddressFamily.InterNetwork)
{
network = IPNetwork2.Parse(
$"{dnsResolverTask.Result.Value}/{hostAndSubnet[1]}");

Parallel.For(IPv4Address.ToInt32(network.Network),
IPv4Address.ToInt32(network.Broadcast) + 1, (i, state) =>
{
if (cancellationToken.IsCancellationRequested)
state.Break();

hostsBag.Add((IPv4Address.FromInt32(i), string.Empty));
});
}
else
{
hostnamesNotResovledBag.Add(hostAndSubnet[0]);
}
network = IPNetwork2.Parse(
$"{dnsResultWithSubnet.Value}/{hostAndSubnet[1]}");

Parallel.For(IPv4Address.ToInt32(network.Network),
IPv4Address.ToInt32(network.Broadcast) + 1, (i, state) =>
{
if (ct.IsCancellationRequested)
state.Break();

hostsBag.Add((IPv4Address.FromInt32(i), string.Empty));
});
}
else
{
hostnamesNotResovledBag.Add(hostAndSubnet[0]);
}
}
else
{
hostnamesNotResovledBag.Add(hostAndSubnet[0]);
}

break;
}
});
}).ConfigureAwait(false);

// Sort list and return
IPAddressComparer comparer = new();
Expand Down
Loading
Loading