Skip to content

Commit

Permalink
Adds more implicit conversion to and from string for DnsLabels.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanedwardes committed Dec 1, 2023
1 parent 8f5827b commit 62bd649
Show file tree
Hide file tree
Showing 21 changed files with 67 additions and 53 deletions.
2 changes: 1 addition & 1 deletion misc/Ae.Dns.Console/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ public DnsHeaderLight(DnsHeader header)
{
ResponseCode = header.ResponseCode;
QueryType = header.QueryType;
Host = header.Host.ToString();
Host = header.Host;
Resolver = (header.Tags.ContainsKey("Resolver") ? header.Tags["Resolver"].ToString() : null) ?? "Unknown";
BlockReason = (header.Tags.ContainsKey("BlockReason") ? header.Tags["BlockReason"].ToString() : null) ?? "None";
Server = (header.Tags.ContainsKey("Server") ? header.Tags["Server"].ToString() : null) ?? "Unknown";
Expand Down
2 changes: 1 addition & 1 deletion samples/BasicUdpServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
using IDnsClient dnsClient = new DnsUdpClient(IPAddress.Parse("1.1.1.1"));

// Allow anything that isn't www.google.com
IDnsFilter dnsFilter = new DnsDelegateFilter(x => x.Header.Host.ToString() != "www.google.com");
IDnsFilter dnsFilter = new DnsDelegateFilter(x => x.Header.Host != "www.google.com");

using IDnsClient filterClient = new DnsFilterClient(dnsFilter, dnsClient);

Expand Down
4 changes: 2 additions & 2 deletions src/Ae.Dns.Client/DnsRecursiveClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ private async Task<DnsMessage> QueryRecursive(DnsMessage query, int depth, Cance
continue;
}

lookup = await LookupNameserverIpAddress(query.Header.Host.ToString(), depth, token);
lookup = await LookupNameserverIpAddress(query.Header.Host, depth, token);
}

throw new DnsClientException($"Too much recursion ({depth}) or too many lookups ({lookups})", query.Header.Host.ToString());
throw new DnsClientException($"Too much recursion ({depth}) or too many lookups ({lookups})", query.Header.Host);
}

private async Task<DnsIpAddressResource> LookupNameserverIpAddress(string nameserver, int depth, CancellationToken token)
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Client/DnsUdpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private static MessageId ToMessageId(DnsMessage message)
return new MessageId
{
Id = message.Header.Id,
Name = message.Header.Host.ToString(),
Name = message.Header.Host,
Type = message.Header.QueryType,
Class = message.Header.QueryClass
};
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Client/Filters/DnsLocalNetworkQueryFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public bool IsPermitted(DnsMessage query)
// See https://www.ietf.org/archive/id/draft-pauly-add-resolver-discovery-01.html
// If you're running your own server on a local network, you probably don't want clients
// bypassing the server and going directly to the upstream (if one happens to respond to this)
if (query.Header.QueryType == DnsQueryType.SVCB && query.Header.Host.ToString() == "_dns.resolver.arpa")
if (query.Header.QueryType == DnsQueryType.SVCB && query.Header.Host == "_dns.resolver.arpa")
{
query.Header.Tags["BlockReason"] = $"{nameof(DnsLocalNetworkQueryFilter)}(DNS resolver discovery)";
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Client/Filters/DnsRemoteSetFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public bool IsPermitted(DnsMessage query)
{
foreach (var filterSet in _filterSets)
{
if (filterSet.Value.Contains(query.Header.Host.ToString()))
if (filterSet.Value.Contains(query.Header.Host))
{
query.Header.Tags["BlockReason"] = $"{nameof(DnsRemoteSetFilter)}({filterSet.Key})";
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Client/Lookup/DnsStaticLookupClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public async Task<DnsMessage> Query(DnsMessage query, CancellationToken token =

foreach (var source in _sources)
{
if (source.TryForwardLookup(query.Header.Host.ToString(), out var addresses))
if (source.TryForwardLookup(query.Header.Host, out var addresses))
{
// This might return zero addresses, but that's OK. We must not return an error.
// For reasoning behind this, see https://www.rfc-editor.org/rfc/rfc4074#section-3
Expand Down
12 changes: 12 additions & 0 deletions src/Ae.Dns.Protocol/DnsLabels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,17 @@ namespace Ae.Dns.Protocol
/// </summary>
/// <param name="labels"></param>
public static implicit operator DnsLabels(string[] labels) => new DnsLabels(labels);

/// <summary>
/// Convert a string to <see cref="DnsLabels"/>.
/// </summary>
/// <param name="labels"></param>
public static implicit operator DnsLabels(string labels) => new DnsLabels(labels);

/// <summary>
/// Convert an instance of <see cref="DnsLabels"/> to a string.
/// </summary>
/// <param name="labels"></param>
public static implicit operator string(DnsLabels labels) => labels.ToString();
}
}
2 changes: 1 addition & 1 deletion src/Ae.Dns.Protocol/DnsQueryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public static DnsMessage CreateQuery(string host, DnsQueryType type = DnsQueryTy
Header = new DnsHeader
{
Id = GenerateId(),
Host = new DnsLabels(host),
Host = host,
QueryType = type,
QueryClass = DnsQueryClass.IN,
OperationCode = DnsOperationCode.QUERY,
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Protocol/Records/DnsDomainResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public sealed class DnsDomainResource : DnsStringResource
/// <summary>
/// Get the value of this entry as a domain name.
/// </summary>
public string Domain => Entries.ToString();
public string Domain => Entries;

/// <inheritdoc/>
public override string ToString() => Domain;
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Protocol/Records/DnsMxResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public sealed class DnsMxResource : DnsStringResource, IEquatable<DnsMxResource>
/// <value>
/// The host name must map directly to one or more address records (A, or AAAA) in the DNS, and must not point to any CNAME records.
/// </value>
public string Exchange => Entries.ToString();
public string Exchange => Entries;

/// <inheritdoc/>
protected override bool CanUseCompression => true;
Expand Down
2 changes: 1 addition & 1 deletion src/Ae.Dns.Protocol/Records/DnsSoaResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void ReadBytes(ReadOnlyMemory<byte> bytes, ref int offset, int length)
}

/// <inheritdoc/>
public override string ToString() => MName.ToString();
public override string ToString() => MName;

/// <inheritdoc/>
public void WriteBytes(Memory<byte> bytes, ref int offset)
Expand Down
6 changes: 4 additions & 2 deletions src/Ae.Dns.Protocol/Records/DnsTextResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Ae.Dns.Protocol.Records
using System.Linq;

namespace Ae.Dns.Protocol.Records
{
/// <summary>
/// Represents a DNS text resource containing a string.
Expand All @@ -9,6 +11,6 @@ public sealed class DnsTextResource : DnsStringResource
protected override bool CanUseCompression => false;

/// <inheritdoc/>
public override string ToString() => '"' + string.Join("\", \"", Entries) + '"';
public override string ToString() => '"' + string.Join("\", \"", Entries.ToArray()) + '"';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ public void WriteBytes(Memory<byte> bytes, ref int offset)
}

/// <inheritdoc/>
public override string ToString() => Entries.ToString();
public override string ToString() => Entries;
}
}
2 changes: 1 addition & 1 deletion tests/Ae.Dns.Tests/Client/ClientTestExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static async Task RunQuery(this IDnsClient client, string host, DnsQueryT

var query = DnsQueryFactory.CreateQuery(host, queryType);
var answer = await retry.Query(query, tokenSource.Token);
Assert.Equal(host, answer.Header.Host.ToString());
Assert.Equal(host, answer.Header.Host);
Assert.Equal(query.Header.Id, answer.Header.Id);
Assert.Equal(expectedResponseCode, answer.Header.ResponseCode);

Expand Down
2 changes: 1 addition & 1 deletion tests/Ae.Dns.Tests/Client/DnsCachingClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task TestCacheEntryWithOnlyAdditionalRecords()
// This is an unrealistic example
new DnsResourceRecord
{
Host = new DnsLabels("example.com"),
Host = "example.com",
Type = DnsQueryType.A,
Resource = new DnsIpAddressResource{IPAddress = IPAddress.Loopback},
TimeToLive = 5
Expand Down
44 changes: 22 additions & 22 deletions tests/Ae.Dns.Tests/Protocol/DnsAnswerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public void ReadAnswer1()

Assert.Equal(DnsQueryClass.IN, message.Header.QueryClass);
Assert.Equal(DnsQueryType.PTR, message.Header.QueryType);
Assert.Equal("1.0.0.127.in-addr.arpa", message.Header.Host.ToString());
Assert.Equal("1.0.0.127.in-addr.arpa", message.Header.Host);
Assert.Equal(0, message.Header.AnswerRecordCount);
Assert.Equal(0, message.Header.AdditionalRecordCount);
Assert.Equal(1, message.Header.QuestionCount);
Expand All @@ -33,11 +33,11 @@ public void ReadAnswer1()
var record = message.Nameservers.Single();
Assert.Equal(DnsQueryType.SOA, record.Type);
Assert.Equal(DnsQueryClass.IN, record.Class);
Assert.Equal("in-addr.arpa", record.Host.ToString());
Assert.Equal("in-addr.arpa", record.Host);

var soaData = (DnsSoaResource)record.Resource;
Assert.Equal("b.in-addr-servers.arpa", soaData.MName.ToString());
Assert.Equal("nstld.iana.org", soaData.RName.ToString());
Assert.Equal("b.in-addr-servers.arpa", soaData.MName);
Assert.Equal("nstld.iana.org", soaData.RName);
Assert.Equal((uint)TimeSpan.Parse("00:36:32").TotalSeconds, record.TimeToLive);
}

Expand All @@ -48,7 +48,7 @@ public void ReadAnswer2()

Assert.Equal(DnsQueryClass.IN, message.Header.QueryClass);
Assert.Equal(DnsQueryType.A, message.Header.QueryType);
Assert.Equal("alanedwardes-my.sharepoint.com", message.Header.Host.ToString());
Assert.Equal("alanedwardes-my.sharepoint.com", message.Header.Host);
Assert.Equal(7, message.Header.AnswerRecordCount);
Assert.Equal(0, message.Header.AdditionalRecordCount);
Assert.Equal(1, message.Header.QuestionCount);
Expand All @@ -61,48 +61,48 @@ public void ReadAnswer2()
var record1 = message.Answers[0];
Assert.Equal(DnsQueryType.CNAME, record1.Type);
Assert.Equal(DnsQueryClass.IN, record1.Class);
Assert.Equal("alanedwardes-my.sharepoint.com", record1.Host.ToString());
Assert.Equal("alanedwardes-my.sharepoint.com", record1.Host);
Assert.Equal((uint)TimeSpan.Parse("01:00:00").TotalSeconds, record1.TimeToLive);
Assert.Equal("alanedwardes.sharepoint.com", ((DnsDomainResource)record1.Resource).Domain);

var record2 = message.Answers[1];
Assert.Equal(DnsQueryType.CNAME, record2.Type);
Assert.Equal(DnsQueryClass.IN, record2.Class);
Assert.Equal("alanedwardes.sharepoint.com", record2.Host.ToString());
Assert.Equal("alanedwardes.sharepoint.com", record2.Host);
Assert.Equal((uint)TimeSpan.Parse("01:00:00").TotalSeconds, record2.TimeToLive);
Assert.Equal("302-ipv4e.clump.dprodmgd104.aa-rt.sharepoint.com", ((DnsDomainResource)record2.Resource).Domain);

var record3 = message.Answers[2];
Assert.Equal(DnsQueryType.CNAME, record3.Type);
Assert.Equal(DnsQueryClass.IN, record3.Class);
Assert.Equal("302-ipv4e.clump.dprodmgd104.aa-rt.sharepoint.com", record3.Host.ToString());
Assert.Equal("302-ipv4e.clump.dprodmgd104.aa-rt.sharepoint.com", record3.Host);
Assert.Equal((uint)TimeSpan.Parse("00:00:30").TotalSeconds, record3.TimeToLive);
Assert.Equal("187170-ipv4e.farm.dprodmgd104.aa-rt.sharepoint.com", ((DnsDomainResource)record3.Resource).Domain);

var record4 = message.Answers[3];
Assert.Equal(DnsQueryType.CNAME, record4.Type);
Assert.Equal(DnsQueryClass.IN, record4.Class);
Assert.Equal("187170-ipv4e.farm.dprodmgd104.aa-rt.sharepoint.com", record4.Host.ToString());
Assert.Equal("187170-ipv4e.farm.dprodmgd104.aa-rt.sharepoint.com", record4.Host);
Assert.Equal((uint)TimeSpan.Parse("00:01:00").TotalSeconds, record4.TimeToLive);
Assert.Equal("187170-ipv4e.farm.dprodmgd104.sharepointonline.com.akadns.net", ((DnsDomainResource)record4.Resource).Domain);

var record5 = message.Answers[4];
Assert.Equal(DnsQueryType.CNAME, record5.Type);
Assert.Equal(DnsQueryClass.IN, record5.Class);
Assert.Equal("187170-ipv4e.farm.dprodmgd104.sharepointonline.com.akadns.net", record5.Host.ToString());
Assert.Equal("187170-ipv4e.farm.dprodmgd104.sharepointonline.com.akadns.net", record5.Host);
Assert.Equal((uint)TimeSpan.Parse("00:05:00").TotalSeconds, record5.TimeToLive);
Assert.Equal("187170-ipv4.farm.dprodmgd104.aa-rt.sharepoint.com.spo-0004.spo-msedge.net", ((DnsDomainResource)record5.Resource).Domain);

var record6 = message.Answers[5];
Assert.Equal(DnsQueryType.CNAME, record6.Type);
Assert.Equal(DnsQueryClass.IN, record6.Class);
Assert.Equal("187170-ipv4.farm.dprodmgd104.aa-rt.sharepoint.com.spo-0004.spo-msedge.net", record6.Host.ToString());
Assert.Equal("187170-ipv4.farm.dprodmgd104.aa-rt.sharepoint.com.spo-0004.spo-msedge.net", record6.Host);
Assert.Equal((uint)TimeSpan.Parse("00:04:00").TotalSeconds, record6.TimeToLive);

var record7 = message.Answers[6];
Assert.Equal(DnsQueryType.A, record7.Type);
Assert.Equal(DnsQueryClass.IN, record7.Class);
Assert.Equal("spo-0004.spo-msedge.net", record7.Host.ToString());
Assert.Equal("spo-0004.spo-msedge.net", record7.Host);
Assert.Equal(IPAddress.Parse("13.107.136.9"), ((DnsIpAddressResource)record7.Resource).IPAddress);
Assert.Equal((uint)TimeSpan.Parse("00:04:00").TotalSeconds, record7.TimeToLive);
}
Expand All @@ -124,7 +124,7 @@ public void ReadAnswer3()
var record = Assert.Single(message.Answers);
Assert.Equal(DnsQueryType.A, record.Type);
Assert.Equal(DnsQueryClass.IN, record.Class);
Assert.Equal("google.com", record.Host.ToString());
Assert.Equal("google.com", record.Host);
Assert.Equal(IPAddress.Parse("216.58.210.206"), ((DnsIpAddressResource)record.Resource).IPAddress);
Assert.Equal((uint)TimeSpan.Parse("00:04:28").TotalSeconds, record.TimeToLive);
}
Expand All @@ -147,7 +147,7 @@ public void ReadAnswer4()
var record1 = message.Answers[0];
Assert.Equal(DnsQueryType.CNAME, record1.Type);
Assert.Equal(DnsQueryClass.IN, record1.Class);
Assert.Equal("alanedwardes.testing.alanedwardes.com", record1.Host.ToString());
Assert.Equal("alanedwardes.testing.alanedwardes.com", record1.Host);
Assert.Equal("alanedwardes.com", ((DnsDomainResource)record1.Resource).Domain);
Assert.Equal((uint)TimeSpan.Parse("00:05:00").TotalSeconds, record1.TimeToLive);

Expand All @@ -160,21 +160,21 @@ public void ReadAnswer4()
var record3 = message.Answers[2];
Assert.Equal(DnsQueryType.A, record3.Type);
Assert.Equal(DnsQueryClass.IN, record3.Class);
Assert.Equal("alanedwardes.com", record3.Host.ToString());
Assert.Equal("alanedwardes.com", record3.Host);
Assert.Equal(IPAddress.Parse("143.204.191.37"), ((DnsIpAddressResource)record3.Resource).IPAddress);
Assert.Equal((uint)TimeSpan.Parse("00:01:00").TotalSeconds, record3.TimeToLive);

var record4 = message.Answers[3];
Assert.Equal(DnsQueryType.A, record4.Type);
Assert.Equal(DnsQueryClass.IN, record4.Class);
Assert.Equal("alanedwardes.com", record4.Host.ToString());
Assert.Equal("alanedwardes.com", record4.Host);
Assert.Equal(IPAddress.Parse("143.204.191.71"), ((DnsIpAddressResource)record4.Resource).IPAddress);
Assert.Equal((uint)TimeSpan.Parse("00:01:00").TotalSeconds, record4.TimeToLive);

var record5 = message.Answers[4];
Assert.Equal(DnsQueryType.A, record5.Type);
Assert.Equal(DnsQueryClass.IN, record5.Class);
Assert.Equal("alanedwardes.com", record5.Host.ToString());
Assert.Equal("alanedwardes.com", record5.Host);
Assert.Equal(IPAddress.Parse("143.204.191.110"), ((DnsIpAddressResource)record5.Resource).IPAddress);
Assert.Equal((uint)TimeSpan.Parse("00:01:00").TotalSeconds, record5.TimeToLive);
}
Expand All @@ -197,7 +197,7 @@ public void ReadAnswer10()
var record1 = message.Answers[0];
Assert.Equal(DnsQueryType.TEXT, record1.Type);
Assert.Equal(DnsQueryClass.IN, record1.Class);
Assert.Equal("_spf.mailgun.org", record1.Host.ToString());
Assert.Equal("_spf.mailgun.org", record1.Host);

var entries = ((DnsTextResource)record1.Resource).Entries;
Assert.Equal(2, entries.Count);
Expand All @@ -224,28 +224,28 @@ public void ReadAnswer11()
var record1 = message.Answers[0];
Assert.Equal(DnsQueryType.NS, record1.Type);
Assert.Equal(DnsQueryClass.IN, record1.Class);
Assert.Equal("google.com", record1.Host.ToString());
Assert.Equal("google.com", record1.Host);
Assert.Equal("ns4.google.com", ((DnsDomainResource)record1.Resource).Domain);
Assert.Equal(21242u, record1.TimeToLive);

var record2 = message.Answers[1];
Assert.Equal(DnsQueryType.NS, record2.Type);
Assert.Equal(DnsQueryClass.IN, record2.Class);
Assert.Equal("google.com", record2.Host.ToString());
Assert.Equal("google.com", record2.Host);
Assert.Equal("ns3.google.com", ((DnsDomainResource)record2.Resource).Domain);
Assert.Equal(21242u, record2.TimeToLive);

var record3 = message.Answers[2];
Assert.Equal(DnsQueryType.NS, record3.Type);
Assert.Equal(DnsQueryClass.IN, record3.Class);
Assert.Equal("google.com", record3.Host.ToString());
Assert.Equal("google.com", record3.Host);
Assert.Equal("ns1.google.com", ((DnsDomainResource)record3.Resource).Domain);
Assert.Equal(21242u, record3.TimeToLive);

var record4 = message.Answers[3];
Assert.Equal(DnsQueryType.NS, record4.Type);
Assert.Equal(DnsQueryClass.IN, record4.Class);
Assert.Equal("google.com", record4.Host.ToString());
Assert.Equal("google.com", record4.Host);
Assert.Equal("ns2.google.com", ((DnsDomainResource)record4.Resource).Domain);
Assert.Equal(21242u, record4.TimeToLive);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/Ae.Dns.Tests/Protocol/DnsDelegatingHandlerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public async Task TestDelegatingHandler(bool isIpv4, DnsQueryType dnsQueryType,
var dnsHandler = new DnsDelegatingHandler(dnsClient.Object, isIpv4) { InnerHandler = mockHandler.Object };
var httpClient = new HttpClient(dnsHandler);

dnsClient.Setup(x => x.Query(It.Is<DnsMessage>(x => x.Header.Host.ToString() == "www.google.com" && x.Header.QueryType == dnsQueryType), It.IsAny<CancellationToken>()))
dnsClient.Setup(x => x.Query(It.Is<DnsMessage>(x => x.Header.Host == "www.google.com" && x.Header.QueryType == dnsQueryType), It.IsAny<CancellationToken>()))
.ReturnsAsync(new DnsMessage
{
Answers = new List<DnsResourceRecord>
Expand Down
2 changes: 1 addition & 1 deletion tests/Ae.Dns.Tests/Protocol/DnsLabelsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public void TestFromArray()
[Fact]
public void TestFromString()
{
var labels = new DnsLabels("one.two.three");
DnsLabels labels = "one.two.three";

Assert.Equal(new[] { "one", "two", "three" }, labels);
}
Expand Down
Loading

0 comments on commit 62bd649

Please sign in to comment.