Skip to content

Commit 4a8266b

Browse files
authored
Adding .NET 6 target and minor improvements (#169)
1 parent 53b94f1 commit 4a8266b

File tree

12 files changed

+158
-84
lines changed

12 files changed

+158
-84
lines changed

samples/MiniDig/MiniDig.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net5.0</TargetFramework>
4+
<TargetFramework>net6.0</TargetFramework>
55
<AssemblyName>MiniDig</AssemblyName>
66
<OutputType>Exe</OutputType>
77
<PackageId>MiniDig</PackageId>
8-
<LangVersion>latest</LangVersion>
98
</PropertyGroup>
109
<PropertyGroup>
1110
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>

src/DnsClient/DnsClient.csproj

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
3-
<VersionPrefix>1.6.1</VersionPrefix>
3+
<VersionPrefix>1.7.0</VersionPrefix>
44
<VersionSuffix Condition="'$(VersionSuffix)'!='' AND '$(BuildNumber)' != ''">$(VersionSuffix)-$(BuildNumber)</VersionSuffix>
55

6-
<TargetFrameworks>net5.0;netstandard1.3;netstandard2.0;netstandard2.1;net45;net471</TargetFrameworks>
6+
<TargetFrameworks>net6.0;net5.0;netstandard1.3;netstandard2.0;netstandard2.1;net45;net471</TargetFrameworks>
77
<DebugType>full</DebugType>
88

99
<Product>DnsClient.NET</Product>
@@ -21,11 +21,12 @@
2121
<PackageTags>dns;client;stub;resolver;name;server;core;service;discovery</PackageTags>
2222

2323
<PackageIcon>icon.png</PackageIcon>
24+
<PackageReadmeFile>README.md</PackageReadmeFile>
2425
<PackageProjectUrl>http://dnsclient.michaco.net</PackageProjectUrl>
2526
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
2627
<WebPage>http://dnsclient.michaco.net</WebPage>
2728
<RepositoryType>git</RepositoryType>
28-
<RepositoryUrl>https://github.com/MichaCo/DnsClient.NET</RepositoryUrl>
29+
<RepositoryUrl>https://github.com/MichaCo/DnsClient.NET</RepositoryUrl>
2930

3031
<GenerateDocumentationFile>true</GenerateDocumentationFile>
3132
<LangVersion>latest</LangVersion>
@@ -40,6 +41,7 @@
4041

4142
<ItemGroup>
4243
<None Include="..\..\icon.png" Pack="true" PackagePath="" />
44+
<None Include="..\..\README.md" Pack="true" PackagePath="\"/>
4345
</ItemGroup>
4446

4547
<ItemGroup Condition=" '$(TargetFramework)' != 'net45' ">

src/DnsClient/DnsDatagramReader.cs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,22 @@
88

99
namespace DnsClient
1010
{
11-
internal class DnsDatagramReader
11+
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
12+
#pragma warning disable CS3002 // Return type is not CLS-compliant
13+
14+
/// <summary>
15+
/// Helper to read from DNS datagrams.
16+
/// </summary>
17+
/// <remarks>
18+
/// The API of this class might change over time and receive breaking changes. Use at own risk.
19+
/// </remarks>
20+
public class DnsDatagramReader
1221
{
1322
public const int IPv6Length = 16;
1423
public const int IPv4Length = 4;
1524
private const byte ReferenceByte = 0xc0;
1625
private const string ACEPrefix = "xn--";
26+
private const int MaxRecursion = 100;
1727

1828
private readonly byte[] _ipV4Buffer = new byte[4];
1929
private readonly byte[] _ipV6Buffer = new byte[16];
@@ -181,18 +191,6 @@ public void Advance(int length)
181191
Index += length;
182192
}
183193

184-
public void SanitizeResult(int expectedIndex, int dataLength)
185-
{
186-
if (Index != expectedIndex)
187-
{
188-
throw new DnsResponseParseException(
189-
message: $"Record reader index out of sync. Expected to read till {expectedIndex} but tried to read till index {Index}.",
190-
data: _data.ToArray(),
191-
index: Index,
192-
length: dataLength);
193-
}
194-
}
195-
196194
public DnsString ReadDnsName()
197195
{
198196
var builder = StringBuilderObjectPool.Default.Get();
@@ -275,8 +273,13 @@ public DnsString ReadQuestionQueryString()
275273
return DnsString.FromResponseQueryString(value);
276274
}
277275

278-
public ICollection<ArraySegment<byte>> ReadLabels()
276+
public IReadOnlyList<ArraySegment<byte>> ReadLabels(int recursion = 0)
279277
{
278+
if (recursion++ >= MaxRecursion)
279+
{
280+
throw new DnsResponseParseException("Max recursion reached.", _data.ToArray(), Index, 0);
281+
}
282+
280283
var result = new List<ArraySegment<byte>>(10);
281284

282285
// read the length byte for the label, then get the content from offset+1 to length
@@ -300,7 +303,7 @@ public ICollection<ArraySegment<byte>> ReadLabels()
300303
}
301304

302305
var subReader = new DnsDatagramReader(_data.SubArrayFromOriginal(subIndex));
303-
var newLabels = subReader.ReadLabels();
306+
var newLabels = subReader.ReadLabels(recursion);
304307
result.AddRange(newLabels); // add range actually much faster than concat and equal to or faster than for-each.. (array copy would work maybe)
305308
return result;
306309
}
@@ -353,6 +356,18 @@ public uint ReadUInt32NetworkOrder()
353356

354357
return (uint)(ReadUInt16NetworkOrder() << 16 | ReadUInt16NetworkOrder());
355358
}
359+
360+
internal void SanitizeResult(int expectedIndex, int dataLength)
361+
{
362+
if (Index != expectedIndex)
363+
{
364+
throw new DnsResponseParseException(
365+
message: $"Record reader index out of sync. Expected to read till {expectedIndex} but tried to read till index {Index}.",
366+
data: _data.ToArray(),
367+
index: Index,
368+
length: dataLength);
369+
}
370+
}
356371
}
357372

358373
internal static class ArraySegmentExtensions
@@ -367,4 +382,7 @@ public static ArraySegment<T> SubArrayFromOriginal<T>(this ArraySegment<T> array
367382
return new ArraySegment<T>(array.Array, startIndex, array.Array.Length - startIndex);
368383
}
369384
}
385+
386+
#pragma warning restore CS3002 // Return type is not CLS-compliant
387+
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
370388
}

src/DnsClient/DnsUdpMessageHandler.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,15 @@ public override async Task<DnsResponseMessage> QueryAsync(
9595

9696
using (var memory = new PooledBytes(readSize))
9797
{
98-
#if !NET45
98+
99+
#if NET6_0_OR_GREATER
100+
int received = await udpClient.Client.ReceiveAsync(
101+
new ArraySegment<byte>(memory.Buffer),
102+
SocketFlags.None,
103+
cancellationToken: cancellationToken).ConfigureAwait(false);
104+
105+
var response = GetResponseMessage(new ArraySegment<byte>(memory.Buffer, 0, received));
106+
#elif !NET45
99107
int received = await udpClient.Client.ReceiveAsync(new ArraySegment<byte>(memory.Buffer), SocketFlags.None).ConfigureAwait(false);
100108

101109
var response = GetResponseMessage(new ArraySegment<byte>(memory.Buffer, 0, received));

src/DnsClient/Internal/PooledBytes.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ private void Dispose(bool disposing)
7070
if (disposing && !_disposed)
7171
{
7272
_disposed = true;
73-
s_pool.Return(_buffer.Array);
73+
s_pool.Return(_buffer.Array, clearArray: true);
7474
}
7575
}
7676
}

src/DnsClient/Interop/Windows/NameResolutionPolicy.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace DnsClient.Windows
1010
{
11+
#if !NET45
12+
1113
internal static class NameResolutionPolicy
1214
{
1315
private static readonly char[] s_splitOn = new char[] { ';' };
@@ -19,12 +21,16 @@ internal static class NameResolutionPolicy
1921
internal static IReadOnlyCollection<NameServer> Resolve(bool includeGenericServers = true, bool includeDirectAccessServers = true)
2022
{
2123
var nameServers = new HashSet<NameServer>();
22-
#if !NET45
24+
25+
#if NET5_0_OR_GREATER
26+
if (!OperatingSystem.IsWindows())
27+
#else
2328
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
29+
#endif
2430
{
2531
return nameServers;
2632
}
27-
#endif
33+
2834
// [MS-GPNRPT] dictates that the NRPT is stored in two separate registry keys.
2935
//
3036
// - The Policy key is pushed down through Group Policy.
@@ -123,4 +129,5 @@ private static void AddServers(HashSet<NameServer> nameServers, string[] names,
123129
}
124130
}
125131
}
132+
#endif
126133
}

src/DnsClient/NameServer.cs

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.IO;
34
using System.Linq;
45
using System.Net;
56
using System.Net.NetworkInformation;
@@ -254,7 +255,7 @@ public static IReadOnlyCollection<NameServer> ResolveNameServers(bool skipIPv6Si
254255
}
255256
catch (Exception ex)
256257
{
257-
logger?.LogInformation(ex, "Resolving name servers using .NET framework failed.");
258+
logger?.LogWarning(ex, "Resolving name servers using .NET framework failed.");
258259
exceptions.Add(ex);
259260
}
260261

@@ -270,7 +271,7 @@ public static IReadOnlyCollection<NameServer> ResolveNameServers(bool skipIPv6Si
270271
}
271272
catch (Exception ex)
272273
{
273-
logger?.LogInformation(ex, "Resolving name servers using native implementation failed.");
274+
logger?.LogWarning(ex, "Resolving name servers using native implementation failed.");
274275
exceptions.Add(ex);
275276
}
276277
}
@@ -305,36 +306,39 @@ public static IReadOnlyCollection<NameServer> ResolveNameServers(bool skipIPv6Si
305306
}
306307

307308
#endif
308-
if (!fallbackToGooglePublicDns && exceptions.Count > 0)
309-
{
310-
if (exceptions.Count > 1)
311-
{
312-
throw new AggregateException("Error resolving name servers", exceptions);
313-
}
314-
else
315-
{
316-
throw new InvalidOperationException("Error resolving name servers", exceptions.First());
317-
}
318-
}
319-
320309
IReadOnlyCollection<NameServer> filtered = nameServers
321310
.Where(p => (p.IPEndPoint.Address.AddressFamily == AddressFamily.InterNetwork
322311
|| p.IPEndPoint.Address.AddressFamily == AddressFamily.InterNetworkV6)
323312
&& (!p.IPEndPoint.Address.IsIPv6SiteLocal || !skipIPv6SiteLocal))
324313
.ToArray();
325314

326-
filtered = ValidateNameServers(filtered, logger);
315+
try
316+
{
317+
filtered = ValidateNameServers(filtered, logger);
318+
}
319+
catch (Exception ex)
320+
{
321+
logger?.LogWarning(ex, "NameServer validation failed.");
322+
exceptions.Add(ex);
323+
}
327324

328-
if (filtered.Count == 0 && fallbackToGooglePublicDns)
325+
if (filtered.Count == 0)
329326
{
330-
logger?.LogWarning("Could not resolve any NameServers, falling back to Google public servers.");
331-
return new NameServer[]
327+
if (!fallbackToGooglePublicDns && exceptions.Count > 0)
332328
{
333-
GooglePublicDnsIPv6,
334-
GooglePublicDns2IPv6,
335-
GooglePublicDns,
336-
GooglePublicDns2,
337-
};
329+
throw new InvalidOperationException("Could not resolve any NameServers.", exceptions.First());
330+
}
331+
else if (fallbackToGooglePublicDns)
332+
{
333+
logger?.LogWarning("Could not resolve any NameServers, falling back to Google public servers.");
334+
return new NameServer[]
335+
{
336+
GooglePublicDns,
337+
GooglePublicDns2,
338+
GooglePublicDnsIPv6,
339+
GooglePublicDns2IPv6
340+
};
341+
}
338342
}
339343

340344
logger?.LogDebug("Resolved {0} name servers: [{1}].", filtered.Count, string.Join(",", filtered.AsEnumerable()));
@@ -357,18 +361,37 @@ public static IReadOnlyCollection<NameServer> ResolveNameServers(bool skipIPv6Si
357361
public static IReadOnlyCollection<NameServer> ResolveNameServersNative()
358362
{
359363
List<NameServer> addresses = new List<NameServer>();
364+
365+
#if NET5_0_OR_GREATER
366+
if (OperatingSystem.IsWindows())
367+
#else
360368
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
369+
#endif
361370
{
362-
var fixedInfo = Windows.IpHlpApi.FixedNetworkInformation.GetFixedInformation();
363-
364-
foreach (var ip in fixedInfo.DnsAddresses)
371+
try
365372
{
366-
addresses.Add(new NameServer(ip, DefaultPort, fixedInfo.DomainName));
373+
var fixedInfo = Windows.IpHlpApi.FixedNetworkInformation.GetFixedInformation();
374+
375+
foreach (var ip in fixedInfo.DnsAddresses)
376+
{
377+
addresses.Add(new NameServer(ip, DefaultPort, fixedInfo.DomainName));
378+
}
367379
}
380+
catch { }
368381
}
382+
#if NET5_0_OR_GREATER
383+
if (OperatingSystem.IsLinux() || OperatingSystem.IsMacOS())
384+
#else
369385
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
386+
#endif
370387
{
371-
addresses = Linux.StringParsingHelpers.ParseDnsAddressesFromResolvConfFile(EtcResolvConfFile);
388+
try
389+
{
390+
addresses = Linux.StringParsingHelpers.ParseDnsAddressesFromResolvConfFile(EtcResolvConfFile);
391+
}
392+
catch (Exception e) when (e is FileNotFoundException || e is UnauthorizedAccessException)
393+
{
394+
}
372395
}
373396

374397
return addresses;
@@ -380,12 +403,7 @@ public static IReadOnlyCollection<NameServer> ResolveNameServersNative()
380403
/// <returns>Returns a collection of name servers from the policy table</returns>
381404
public static IReadOnlyCollection<NameServer> ResolveNameResolutionPolicyServers()
382405
{
383-
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
384-
{
385-
return NameResolutionPolicy.Resolve();
386-
}
387-
388-
return Array.Empty<NameServer>();
406+
return NameResolutionPolicy.Resolve();
389407
}
390408

391409
#endif
@@ -413,16 +431,20 @@ private static IReadOnlyCollection<NameServer> QueryNetworkInterfaces()
413431
var result = new HashSet<NameServer>();
414432

415433
var adapters = NetworkInterface.GetAllNetworkInterfaces();
434+
if (adapters == null)
435+
{
436+
return result.ToArray();
437+
}
416438

417439
foreach (NetworkInterface networkInterface in
418440
adapters
419-
.Where(p => (p.OperationalStatus == OperationalStatus.Up || p.OperationalStatus == OperationalStatus.Unknown)
441+
.Where(p => p != null && (p.OperationalStatus == OperationalStatus.Up || p.OperationalStatus == OperationalStatus.Unknown)
420442
&& p.NetworkInterfaceType != NetworkInterfaceType.Loopback))
421443
{
422-
var properties = networkInterface.GetIPProperties();
444+
var properties = networkInterface?.GetIPProperties();
423445

424446
// Can be null under mono for whatever reason...
425-
if (properties == null)
447+
if (properties?.DnsAddresses == null)
426448
{
427449
continue;
428450
}

0 commit comments

Comments
 (0)