Skip to content
Merged
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
6 changes: 3 additions & 3 deletions DnsClientX.Benchmarks/DnsClientX.Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<AssemblyTitle>DnsClientX Benchmarks</AssemblyTitle>
<Title>DnsClientX Performance Benchmarks</Title>
<Description>Performance benchmarks for DnsClientX DNS library using BenchmarkDotNet.</Description>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<Company>Evotec</Company>
<Authors>Przemyslaw Klys</Authors>
<Copyright>(c) 2011 - 2025 Przemyslaw Klys @ Evotec. All rights reserved.</Copyright>
Expand Down
6 changes: 3 additions & 3 deletions DnsClientX.Cli/DnsClientX.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<AssemblyTitle>DnsClientX CLI</AssemblyTitle>
<Title>DnsClientX Command Line Interface</Title>
<Description>Command-line interface for DnsClientX DNS library. Provides quick DNS queries and scripting capabilities.</Description>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<Company>Evotec</Company>
<Authors>Przemyslaw Klys</Authors>
<Copyright>(c) 2011 - 2025 Przemyslaw Klys @ Evotec. All rights reserved.</Copyright>
Expand Down
6 changes: 3 additions & 3 deletions DnsClientX.Examples/DnsClientX.Examples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
<AssemblyTitle>DnsClientX Examples</AssemblyTitle>
<Title>DnsClientX Examples</Title>
<Description>Example applications demonstrating DnsClientX library features and capabilities.</Description>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<Company>Evotec</Company>
<Authors>Przemyslaw Klys</Authors>
<Copyright>(c) 2011 - 2025 Przemyslaw Klys @ Evotec. All rights reserved.</Copyright>
Expand Down
8 changes: 4 additions & 4 deletions DnsClientX.PowerShell/DnsClientX.PowerShell.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
service discovery, zone transfers, and DNS updates.</Description>
<AssemblyName>DnsClientX.PowerShell</AssemblyName>
<AssemblyTitle>DnsClientX PowerShell Module</AssemblyTitle>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<Company>Evotec</Company>
<Authors>Przemyslaw Klys</Authors>
Expand Down Expand Up @@ -55,4 +55,4 @@
<ItemGroup>
<ProjectReference Include="..\DnsClientX\DnsClientX.csproj" />
</ItemGroup>
</Project>
</Project>
14 changes: 10 additions & 4 deletions DnsClientX.Tests/CdBitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,20 @@ private static byte[] CreateDnsHeader() {
return bytes;
}

private static int GetFreePort() {
private static int GetFreeTcpPort() {
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}

private static int GetFreeUdpPort() {
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint!).Port;
}

private static async Task<byte[]> RunUdpServerAsync(int port, byte[] response, CancellationToken token) {
using var udp = new UdpClient(new IPEndPoint(IPAddress.Loopback, port));
UdpReceiveResult result = await udp.ReceiveAsync();
Expand Down Expand Up @@ -77,7 +83,7 @@ private static void AssertCdBit(byte[] query, string name, uint expectedTtl) {
/// </summary>
[Fact]
public async Task UdpRequest_ShouldIncludeCdBit_WhenConfigured() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand All @@ -104,7 +110,7 @@ await DnsWireResolveUdp.ResolveWireFormatUdp(
/// </summary>
[Fact]
public async Task TcpRequest_ShouldIncludeCdBit_WhenConfigured() {
int port = GetFreePort();
int port = GetFreeTcpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var tcpTask = RunTcpServerAsync(port, response, cts.Token);
Expand All @@ -130,7 +136,7 @@ await DnsWireResolveTcp.ResolveWireFormatTcp(
/// </summary>
[Fact]
public async Task UdpRequest_ShouldIncludeCdBit_WhenValidateDnsSecTrue() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand Down
2 changes: 1 addition & 1 deletion DnsClientX.Tests/CliDnssecFlagTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private static void AssertDoCdBits(byte[] query, string name) {
/// </summary>
[Fact]
public async Task Cli_ShouldSetDoAndCdBits_WhenDnssecValidationEnabled() {
int port = TestUtilities.GetFreePort();
int port = TestUtilities.GetFreeUdpPort();

SystemInformation.SetDnsServerProvider(() => new List<string> { "127.0.0.1" });

Expand Down
6 changes: 3 additions & 3 deletions DnsClientX.Tests/DnsClientX.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<AssemblyTitle>DnsClientX Tests</AssemblyTitle>
<Title>DnsClientX Unit Tests</Title>
<Description>Unit tests for DnsClientX DNS library.</Description>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<Company>Evotec</Company>
<Authors>Przemyslaw Klys</Authors>
<Copyright>(c) 2011 - 2025 Przemyslaw Klys @ Evotec. All rights reserved.</Copyright>
Expand Down
18 changes: 12 additions & 6 deletions DnsClientX.Tests/EdnsDoBitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,20 @@ private static byte[] CreateDnsHeader() {
return bytes;
}

private static int GetFreePort() {
private static int GetFreeTcpPort() {
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}

private static int GetFreeUdpPort() {
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint!).Port;
}

private static async Task<byte[]> RunUdpServerAsync(int port, byte[] response, CancellationToken token) {
using var udp = new UdpClient(new IPEndPoint(IPAddress.Loopback, port));
UdpReceiveResult result = await udp.ReceiveAsync();
Expand Down Expand Up @@ -117,7 +123,7 @@ private static void AssertBufferSize(byte[] query, string name, ushort size) {
/// </summary>
[Fact]
public async Task UdpRequest_ShouldIncludeDoBit_WhenRequested() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand All @@ -144,7 +150,7 @@ await DnsWireResolveUdp.ResolveWireFormatUdp(
/// </summary>
[Fact]
public async Task TcpRequest_ShouldIncludeDoBit_WhenRequested() {
int port = GetFreePort();
int port = GetFreeTcpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var tcpTask = RunTcpServerAsync(port, response, cts.Token);
Expand All @@ -170,7 +176,7 @@ await DnsWireResolveTcp.ResolveWireFormatTcp(
/// </summary>
[Fact]
public async Task UdpRequest_ShouldUseCustomBufferSize() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand All @@ -197,7 +203,7 @@ await DnsWireResolveUdp.ResolveWireFormatUdp(
/// </summary>
[Fact]
public async Task UdpRequest_ShouldUseBufferSize_FromEdnsOptions() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand Down Expand Up @@ -227,7 +233,7 @@ await DnsWireResolveUdp.ResolveWireFormatUdp(
/// </summary>
[Fact]
public async Task UdpRequest_ShouldNotSetDoBit_WhenDnssecNotRequested() {
int port = GetFreePort();
int port = GetFreeUdpPort();
var response = CreateDnsHeader();
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var udpTask = RunUdpServerAsync(port, response, cts.Token);
Expand Down
8 changes: 3 additions & 5 deletions DnsClientX.Tests/EdnsOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ private static byte[] CreateDnsHeader() {
}

private static int GetFreePort() {
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint!).Port;
}

private static async Task<byte[]> RunUdpServerAsync(int port, byte[] response, CancellationToken token) {
Expand Down
6 changes: 4 additions & 2 deletions DnsClientX.Tests/ResolveFirst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ public async Task ShouldWorkForA(DnsEndpoint endpoint) {
using var Client = new ClientX(endpoint);
var answer = await Client.ResolveFirst("evotec.pl", DnsRecordType.A, cancellationToken: CancellationToken.None);
Assert.True(answer != null);
Assert.True(answer.Value.Name == "evotec.pl");
Assert.True(answer.Value.Type == DnsRecordType.A);
Comment on lines 60 to 61
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertions on lines 60-61 lack descriptive messages while the new assertions below them have descriptive messages. For consistency with the improvements in this PR, consider adding descriptive messages to these assertions as well, such as "Expected a non-null answer" for line 60 and "Expected A record but got {answer.Value.Type}" for line 61.

Copilot uses AI. Check for mistakes.
Assert.True(!string.IsNullOrWhiteSpace(answer.Value.Name), "Expected answer name to not be empty");
Assert.True(System.Net.IPAddress.TryParse(answer.Value.Data, out var ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork, $"Expected A record data to be an IPv4 address but got '{answer.Value.Data}' (name '{answer.Value.Name}', original '{answer.Value.OriginalName}')");
}

/// <summary>
Expand Down Expand Up @@ -111,8 +112,9 @@ public void ShouldWorkForA_Sync(DnsEndpoint endpoint) {
using var Client = new ClientX(endpoint);
var answer = Client.ResolveFirstSync("evotec.pl", DnsRecordType.A, cancellationToken: CancellationToken.None);
Assert.True(answer != null);
Assert.True(answer.Value.Name == "evotec.pl");
Assert.True(answer.Value.Type == DnsRecordType.A);
Comment on lines 114 to 115
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertions on lines 114-115 lack descriptive messages while the new assertions below them have descriptive messages. For consistency with the improvements in this PR, consider adding descriptive messages to these assertions as well, such as "Expected a non-null answer" for line 114 and "Expected A record but got {answer.Value.Type}" for line 115.

Copilot uses AI. Check for mistakes.
Assert.True(!string.IsNullOrWhiteSpace(answer.Value.Name), "Expected answer name to not be empty");
Assert.True(System.Net.IPAddress.TryParse(answer.Value.Data, out var ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork, $"Expected A record data to be an IPv4 address but got '{answer.Value.Data}' (name '{answer.Value.Name}', original '{answer.Value.OriginalName}')");
}
}
}
9 changes: 5 additions & 4 deletions DnsClientX.Tests/ResolveSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,11 @@ public void ShouldWorkForFirstSyncA(DnsEndpoint endpoint) {
if (ShouldSkipEndpoint(endpoint)) return;
using var client = new ClientX(endpoint);
var answer = client.ResolveFirstSync("evotec.pl", DnsRecordType.A, cancellationToken: CancellationToken.None);
Assert.True(answer != null);
Assert.True(answer.Value.Name == "evotec.pl");
Assert.True(answer.Value.Type == DnsRecordType.A);
Assert.True(answer.Value.Data.Length > 0);
Assert.True(answer != null, "Expected a non-null answer");
Assert.True(answer.Value.Type == DnsRecordType.A, $"Expected A record but got {answer.Value.Type}");
Assert.True(!string.IsNullOrWhiteSpace(answer.Value.Name), "Expected answer name to not be empty");
Assert.True(!string.IsNullOrWhiteSpace(answer.Value.Data), "Expected answer data to not be empty");
Assert.True(System.Net.IPAddress.TryParse(answer.Value.Data, out var ipAddress) && ipAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork, $"Expected A record data to be an IPv4 address but got '{answer.Value.Data}' (name '{answer.Value.Name}', original '{answer.Value.OriginalName}')");
}

/// <summary>
Expand Down
35 changes: 34 additions & 1 deletion DnsClientX.Tests/TestSkipHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,40 @@ internal static class TestSkipHelpers
{
internal static bool ShouldSkipEndpoint(DnsEndpoint endpoint, ITestOutputHelper? output = null)
{
return ShouldSkipSystemTcp(endpoint, output) || ShouldSkipOdoh(endpoint, output);
return ShouldSkipSystemUdp(endpoint, output) || ShouldSkipSystemTcp(endpoint, output) || ShouldSkipOdoh(endpoint, output);
}

private static bool ShouldSkipSystemUdp(DnsEndpoint endpoint, ITestOutputHelper? output)
{
if (endpoint != DnsEndpoint.System)
{
return false;
}

var servers = SystemInformation.GetDnsFromActiveNetworkCard();
if (servers == null || servers.Count == 0)
{
output?.WriteLine("[Diagnostic] System UDP DNS skipped: no active DNS servers detected.");
return true;
}

var allLoopback = true;
foreach (var server in servers)
{
if (IPAddress.TryParse(server, out var ip) && !IPAddress.IsLoopback(ip))
{
allLoopback = false;
break;
}
}

if (allLoopback)
{
output?.WriteLine("[Diagnostic] System UDP DNS skipped: only loopback resolvers detected.");
return true;
}

return false;
}

private static bool ShouldSkipSystemTcp(DnsEndpoint endpoint, ITestOutputHelper? output)
Expand Down
10 changes: 10 additions & 0 deletions DnsClientX.Tests/TestUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,21 @@
namespace DnsClientX.Tests {
internal static class TestUtilities {
public static int GetFreePort() {
return GetFreeTcpPort();
}

public static int GetFreeTcpPort() {
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}

public static int GetFreeUdpPort() {
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint!).Port;
}
}
}
8 changes: 3 additions & 5 deletions DnsClientX.Tests/UdpClientDisposeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,9 @@ private static byte[] CreateDnsHeader() {
}

private static int GetFreePort() {
TcpListener listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
int port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 0));
return ((IPEndPoint)socket.LocalEndPoint!).Port;
}

private static async Task<int> RunUdpServerCapturePortAsync(int port, byte[] response, CancellationToken token) {
Expand Down
12 changes: 11 additions & 1 deletion DnsClientX/DnsClientX.ResolveFirst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,17 @@ public partial class ClientX {
retryDelayMs: retryDelayMs,
cancellationToken: cancellationToken).ConfigureAwait(false);

return res.Answers?.FirstOrDefault(x => x.Type == type);
if (res.Answers == null || res.Answers.Length == 0) {
return null;
}

foreach (DnsAnswer answer in res.Answers) {
if (answer.Type == type) {
return answer;
}
}

return null;
}

/// <summary>
Expand Down
8 changes: 4 additions & 4 deletions DnsClientX/DnsClientX.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
</Description>
<AssemblyName>DnsClientX</AssemblyName>
<AssemblyTitle>DnsClientX</AssemblyTitle>
<VersionPrefix>1.0.6</VersionPrefix>
<AssemblyVersion>1.0.6</AssemblyVersion>
<FileVersion>1.0.6</FileVersion>
<VersionPrefix>1.0.7</VersionPrefix>
<AssemblyVersion>1.0.7</AssemblyVersion>
<FileVersion>1.0.7</FileVersion>
<TargetFrameworks Condition=" '$([MSBuild]::IsOsPlatform(`Windows`))' ">
netstandard2.0;net472;net8.0;net9.0
</TargetFrameworks>
Expand Down Expand Up @@ -80,4 +80,4 @@
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
</Project>
</Project>
2 changes: 1 addition & 1 deletion Module/Build/Build-Module.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Build-Module -ModuleName 'DnsClientX' {
# Usual defaults as per standard module
$Manifest = [ordered] @{
ModuleVersion = '1.0.6'
ModuleVersion = '1.0.7'
CompatiblePSEditions = @('Desktop', 'Core')
GUID = '77fa806c-70b7-48d9-8b88-942ed73f24ed'
Author = 'Przemyslaw Klys'
Expand Down
4 changes: 2 additions & 2 deletions Module/DnsClientX.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
FunctionsToExport = @()
GUID = '77fa806c-70b7-48d9-8b88-942ed73f24ed'
HelpInfoURI = 'https://github.com/EvotecIT/DnsClientX/blob/master/README.md'
ModuleVersion = '1.0.6'
ModuleVersion = '1.0.7'
PowerShellVersion = '5.1'
PrivateData = @{
PSData = @{
Expand All @@ -19,4 +19,4 @@
}
}
RootModule = 'DnsClientX.psm1'
}
}
Loading