Skip to content

Commit

Permalink
Adds initial implementation for DNS zone files.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanedwardes committed Feb 8, 2024
1 parent 5089a3d commit 7ef9fd9
Show file tree
Hide file tree
Showing 25 changed files with 654 additions and 187 deletions.
8 changes: 6 additions & 2 deletions misc/Ae.Dns.Console/Program.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
using Ae.Dns.Client;
using Ae.Dns.Client.Filters;
using Ae.Dns.Client.Lookup;
using Ae.Dns.Client.Zone;
using Ae.Dns.Metrics.InfluxDb;
using Ae.Dns.Protocol;
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Zone;
using Ae.Dns.Server;
using Ae.Dns.Server.Http;
using App.Metrics;
Expand Down Expand Up @@ -211,7 +211,11 @@ async Task ReportStats(CancellationToken token)
if (dnsConfiguration.UpdateZoneName != null && dnsConfiguration.UpdateZoneFile != null)
{
#pragma warning disable CS0618 // Type or member is obsolete
updateClient = new DnsUpdateClient(new FileDnsZone(dnsConfiguration.UpdateZoneName, new FileInfo(dnsConfiguration.UpdateZoneFile)));
updateClient = new DnsUpdateClient(new DnsZone
{
Origin = dnsConfiguration.UpdateZoneName,
DefaultTtl = TimeSpan.FromHours(1)
});
#pragma warning restore CS0618 // Type or member is obsolete
}

Expand Down
24 changes: 17 additions & 7 deletions src/Ae.Dns.Client/DnsUpdateClient.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Ae.Dns.Client.Zone;
using Ae.Dns.Protocol;
using Ae.Dns.Protocol;
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Records;
using Ae.Dns.Protocol.Zone;
using System;
using System.Collections.Generic;
using System.Linq;
Expand All @@ -28,26 +28,36 @@ public DnsUpdateClient(IDnsZone dnsZone)
}

/// <inheritdoc/>
public async Task<DnsMessage> Query(DnsMessage query, CancellationToken token = default)
public Task<DnsMessage> Query(DnsMessage query, CancellationToken token = default)
{
query.EnsureOperationCode(DnsOperationCode.UPDATE);

var hostnames = query.Nameservers.Select(x => x.Host).ToArray();

void RemoveStaleRecords(ICollection<DnsResourceRecord> records)
void ChangeRecords(ICollection<DnsResourceRecord> records)
{
foreach (var recordToRemove in records.Where(x => hostnames.Contains(x.Host)).ToArray())
{
records.Remove(recordToRemove);
}

foreach (var nameserver in query.Nameservers)
{
records.Add(nameserver);
}
};

if (query.Nameservers.Count > 0 && hostnames.Any(x => x.Last() != _dnsZone.Name) && await _dnsZone.ChangeRecords(RemoveStaleRecords, query.Nameservers, token))
if (query.Nameservers.Count > 0 && hostnames.Any(x => x.Last() != _dnsZone.Origin))
{
return query.CreateAnswerMessage(DnsResponseCode.NoError, ToString());
lock (_dnsZone)
{
ChangeRecords(_dnsZone.Records);
}

return Task.FromResult(query.CreateAnswerMessage(DnsResponseCode.NoError, ToString()));
}

return query.CreateAnswerMessage(DnsResponseCode.Refused, ToString());
return Task.FromResult(query.CreateAnswerMessage(DnsResponseCode.Refused, ToString()));
}

/// <inheritdoc/>
Expand Down
4 changes: 2 additions & 2 deletions src/Ae.Dns.Client/Lookup/DnsZoneLookup.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Ae.Dns.Client.Zone;
using Ae.Dns.Protocol.Records;
using Ae.Dns.Protocol.Records;
using Ae.Dns.Protocol.Zone;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down
117 changes: 0 additions & 117 deletions src/Ae.Dns.Client/Zone/FileDnsZone.cs

This file was deleted.

33 changes: 0 additions & 33 deletions src/Ae.Dns.Client/Zone/IDnsZone.cs

This file was deleted.

16 changes: 15 additions & 1 deletion src/Ae.Dns.Protocol/Records/DnsDomainResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace Ae.Dns.Protocol.Records
using Ae.Dns.Protocol.Zone;

namespace Ae.Dns.Protocol.Records
{
/// <summary>
/// Represents a DNS text resource containing a domain name.
Expand All @@ -15,5 +17,17 @@ public sealed class DnsDomainResource : DnsStringResource

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

/// <inheritdoc/>
public override string ToZone(IDnsZone zone)
{
return zone.ToFormattedHost(Entries);
}

/// <inheritdoc/>
public override void FromZone(IDnsZone zone, string input)
{
Entries = zone.FromFormattedHost(input);
}
}
}
14 changes: 14 additions & 0 deletions src/Ae.Dns.Protocol/Records/DnsIpAddressResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Zone;
using System;
using System.Collections.Generic;
using System.Net;
Expand Down Expand Up @@ -60,5 +61,18 @@ public void WriteBytes(Memory<byte> bytes, ref int offset)
address.CopyTo(bytes.Slice(offset).Span);
offset += address.Length;
}


/// <inheritdoc/>
public string ToZone(IDnsZone zone)
{
return IPAddress.ToString();
}

/// <inheritdoc/>
public void FromZone(IDnsZone zone, string input)
{
IPAddress = IPAddress.Parse(input);
}
}
}
17 changes: 16 additions & 1 deletion src/Ae.Dns.Protocol/Records/DnsMxResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Zone;
using System;

namespace Ae.Dns.Protocol.Records
Expand Down Expand Up @@ -53,7 +54,21 @@ public override void ReadBytes(ReadOnlyMemory<byte> bytes, ref int offset, int l
}

/// <inheritdoc/>
public override string ToString() => Exchange;
public override void FromZone(IDnsZone zone, string input)
{
var parts = input.Split(null);
Preference = ushort.Parse(parts[0]);
Entries = zone.FromFormattedHost(parts[1]);
}

/// <inheritdoc/>
public override string ToZone(IDnsZone zone)
{
return $"{Preference} {zone.ToFormattedHost(Entries)}";
}

/// <inheritdoc/>
public override string ToString() => $"{Preference} {Entries}";

/// <inheritdoc/>
public override void WriteBytes(Memory<byte> bytes, ref int offset)
Expand Down
15 changes: 14 additions & 1 deletion src/Ae.Dns.Protocol/Records/DnsOptResource.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Ae.Dns.Protocol.Zone;
using System;
namespace Ae.Dns.Protocol.Records
{
/// <summary>
Expand Down Expand Up @@ -46,6 +47,18 @@ public void WriteBytes(Memory<byte> bytes, ref int offset)
offset += Raw.Length;
}

/// <inheritdoc/>
public string ToZone(IDnsZone zone)
{
throw new NotImplementedException();
}

/// <inheritdoc/>
public void FromZone(IDnsZone zone, string input)
{
throw new NotImplementedException();
}

/// <inheritdoc/>
public override string ToString() => $"Raw: {Raw.Length} bytes";
}
Expand Down
22 changes: 21 additions & 1 deletion src/Ae.Dns.Protocol/Records/DnsResourceRecord.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Zone;
using System;
using System.Linq;

Expand All @@ -7,7 +8,7 @@ namespace Ae.Dns.Protocol.Records
/// <summary>
/// Represents metadata around a DNS resource record returned by a DNS server.
/// </summary>
public sealed class DnsResourceRecord : IEquatable<DnsResourceRecord>, IDnsByteArrayReader, IDnsByteArrayWriter
public sealed class DnsResourceRecord : IEquatable<DnsResourceRecord>, IDnsByteArrayReader, IDnsByteArrayWriter, IDnsZoneConverter
{
/// <summary>
/// The type of DNS query.
Expand Down Expand Up @@ -118,5 +119,24 @@ public void WriteBytes(Memory<byte> bytes, ref int offset)
// Advance the offset with the size of the resource
offset += resourceSize;
}

/// <inheritdoc/>
public string ToZone(IDnsZone zone)
{
return $"{zone.ToFormattedHost(Host)} {Class} {Type} {Resource.ToZone(zone)}";
}

/// <inheritdoc/>
public void FromZone(IDnsZone zone, string input)
{
var parts = input.Split(null, 4);

Host = zone.FromFormattedHost(parts[0]);
Class = (DnsQueryClass)Enum.Parse(typeof(DnsQueryClass), parts[1]);
Type = (DnsQueryType)Enum.Parse(typeof(DnsQueryType), parts[2]);
TimeToLive = (uint)zone.DefaultTtl.TotalSeconds;
Resource = CreateResourceRecord(Type);
Resource.FromZone(zone, parts[3]);
}
}
}
Loading

0 comments on commit 7ef9fd9

Please sign in to comment.