Skip to content

Commit

Permalink
Adds new update packet style, now allow encoding "unknown" resources.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanedwardes committed Feb 11, 2024
1 parent 36ec2d8 commit a194913
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/Ae.Dns.Client/DnsUpdateClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -53,7 +54,7 @@ void ChangeRecords(ICollection<DnsResourceRecord> records)
}
};

if (query.Nameservers.Count > 0 && hostnames.All(x => x.ToString().EndsWith(_dnsZone.Origin)))
if (query.Nameservers.Count > 0 && hostnames.All(x => !Regex.IsMatch(x, @"\s")) && hostnames.All(x => x.ToString().EndsWith(_dnsZone.Origin)))
{
await _dnsZone.Update(ChangeRecords);
return query.CreateAnswerMessage(DnsResponseCode.NoError, ToString());
Expand Down
5 changes: 3 additions & 2 deletions src/Ae.Dns.Protocol/Records/DnsUnknownResource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,14 @@ public void ReadBytes(ReadOnlyMemory<byte> bytes, ref int offset, int length)
/// <inheritdoc/>
public string ToZone(IDnsZone zone)
{
throw new NotImplementedException();
return $"({Convert.ToBase64String(Raw.ToArray())})";
}

/// <inheritdoc/>
public void FromZone(IDnsZone zone, string input)
{
throw new NotImplementedException();
var base64 = input.Trim().Trim(new char[] { '(', ')' });
Raw = Convert.FromBase64String(base64);
}

/// <inheritdoc/>
Expand Down
6 changes: 6 additions & 0 deletions src/Ae.Dns.Protocol/Zone/DnsZone.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -154,6 +155,11 @@ public string FromFormattedHost(string host)
/// <inheritdoc/>
public string ToFormattedHost(string host)
{
if (Regex.IsMatch(host, @"\s"))
{
throw new InvalidOperationException($"Hostname '{host}' contains invalid characters");
}

if (host == Origin)
{
return "@";
Expand Down
26 changes: 26 additions & 0 deletions tests/Ae.Dns.Tests/Client/DnsUpdateClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,32 @@ public async Task TestWrongZone()
Assert.Empty(zone.Records);
}

[Fact]
public async Task TestWhitespaceHostname()
{
var zone = new TestDnsZone();

var updateClient = new DnsUpdateClient(zone);

var result = await updateClient.Query(new DnsMessage
{
Header = new DnsHeader { OperationCode = DnsOperationCode.UPDATE },
Nameservers = new[]
{
new DnsResourceRecord
{
Type = DnsQueryType.A,
Class = DnsQueryClass.IN,
Host = "test me.example.com",
Resource = new DnsIpAddressResource { IPAddress = IPAddress.Parse("192.168.0.1") }
}
}
});
Assert.Equal(DnsResponseCode.Refused, result.Header.ResponseCode);

Assert.Empty(zone.Records);
}

[Fact]
public async Task TestAddRecords()
{
Expand Down
6 changes: 6 additions & 0 deletions tests/Ae.Dns.Tests/Protocol/DnsUpdateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@ public void ReadUpdate2()
{
var message = DnsByteExtensions.FromBytes<DnsMessage>(SampleDnsPackets.Update2);
}

[Fact]
public void ReadUpdate3()
{
var message = DnsByteExtensions.FromBytes<DnsMessage>(SampleDnsPackets.Update3);
}
}
}
5 changes: 5 additions & 0 deletions tests/Ae.Dns.Tests/SampleDnsPackets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ public static class SampleDnsPackets
177,183,40,0,0,1,0,2,0,1,0,0,4,104,111,109,101,0,0,6,0,1,13,88,82,49,56,45,48,70,45,66,50,45,52,69,192,12,0,1,0,254,0,0,0,0,0,0,192,22,0,28,0,254,0,0,0,0,0,0,192,22,0,16,0,254,0,0,0,0,0,35,34,48,48,101,51,53,98,97,56,49,52,53,50,57,99,57,98,98,99,100,51,100,101,52,101,57,98,55,100,50,51,101,57,54,55
};

public static readonly byte[] Update3 = new byte[]
{
197,1,40,0,0,1,0,1,0,2,0,0,4,104,111,109,101,0,0,6,0,1,12,101,117,102,121,32,82,111,98,111,86,97,99,192,12,0,255,0,254,0,0,0,0,0,0,192,22,0,1,0,1,0,0,14,16,0,4,192,168,178,243,192,22,0,49,0,1,0,0,14,16,0,35,0,0,1,71,63,137,34,61,192,202,183,33,145,161,38,88,247,91,91,17,134,221,161,136,142,110,218,234,187,149,18,126,121,106,33
};

private static IList<byte[]> ReadBatch(FileInfo fileInfo)
{
var answers = new List<byte[]>();
Expand Down
19 changes: 18 additions & 1 deletion tests/Ae.Dns.Tests/Zone/DnsZoneTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol;
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Records;
using Ae.Dns.Protocol.Zone;
using System;
Expand Down Expand Up @@ -194,6 +195,22 @@ public async Task TestLoadZone2()
zone.DeserializeZone(await File.ReadAllTextAsync("Zone/test2.zone"));
}

[Fact]
public async Task TestLoadZone3()
{
var message = DnsByteExtensions.FromBytes<DnsMessage>(SampleDnsPackets.Update3);

// This packet has bad hostnames
message.Nameservers[0].Host = "eufyRoboVac.home";
message.Nameservers[1].Host = "eufyRoboVac.home";

var zone = new DnsZone(message.Nameservers);

var serialized = await RoundTripRecords(zone.Records.ToArray());

Assert.NotNull(serialized);
}

public async Task<string> RoundTripRecords(params DnsResourceRecord[] records)
{
var originalZone = new DnsZone
Expand Down

0 comments on commit a194913

Please sign in to comment.