Skip to content

Commit

Permalink
Moves to a formal zone update model in DnsZoneUpdateClient.
Browse files Browse the repository at this point in the history
  • Loading branch information
alanedwardes committed Feb 14, 2024
1 parent 267e89e commit 32f874b
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 35 deletions.
5 changes: 0 additions & 5 deletions src/Ae.Dns.Client/DnsRawClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,6 @@ public async Task<DnsRawClientResponse> Query(Memory<byte> buffer, DnsRawClientR
throw;
}

if (query.Header.OperationCode == Protocol.Enums.DnsOperationCode.UPDATE)
{
_logger.LogInformation("Update query {Bytes}", DnsByteExtensions.ToDebugString(queryBuffer.ToArray()));
}

query.Header.Tags.Add("Sender", request.SourceEndpoint);
query.Header.Tags.Add("Server", request.ServerName);

Expand Down
46 changes: 16 additions & 30 deletions src/Ae.Dns.Client/DnsZoneUpdateClient.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
using Ae.Dns.Protocol;
using Ae.Dns.Protocol.Enums;
using Ae.Dns.Protocol.Records;
using Ae.Dns.Protocol.Zone;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -39,37 +35,27 @@ public async Task<DnsMessage> Query(DnsMessage query, CancellationToken token =
query.EnsureQueryType(DnsQueryType.SOA);
query.EnsureHost(_dnsZone.Origin);

// TODO: this logic is bad
var hostnames = query.Nameservers.Select(x => x.Host.ToString()).ToArray();
var addresses = query.Nameservers.Select(x => x.Resource).OfType<DnsIpAddressResource>().Select(x => x.IPAddress).ToArray();

DnsResponseCode ChangeRecords(ICollection<DnsResourceRecord> records)
// Early out without requiring a lock (e.g. in the zone update)
var firstPreReqsCheckResponseCode = _dnsZone.TestZoneUpdatePreRequisites(query);
if (firstPreReqsCheckResponseCode != DnsResponseCode.NoError)
{
foreach (var recordToRemove in records.Where(x => hostnames.Contains(x.Host.ToString())).ToArray())
{
records.Remove(recordToRemove);
}

foreach (var recordToRemove in records.Where(x => x.Resource is DnsIpAddressResource ipr && addresses.Contains(ipr.IPAddress)).ToArray())
{
records.Remove(recordToRemove);
}
return query.CreateAnswerMessage(firstPreReqsCheckResponseCode, ToString());
}

foreach (var nameserver in query.Nameservers)
// Run the zone update and return the response
return query.CreateAnswerMessage(await _dnsZone.Update(records =>
{
// The update method locks, it's unlikely but things could have changed since
// we ran the first pre-reqs check (given that can happen in parallel)
var responseCode = _dnsZone.TestZoneUpdatePreRequisites(query);
if (responseCode != DnsResponseCode.NoError)
{
records.Add(nameserver);
return responseCode;
}

return DnsResponseCode.NoError;
};

if (query.Nameservers.Count > 0 && hostnames.All(x => !Regex.IsMatch(x, @"\s")) && hostnames.All(x => x.ToString().EndsWith(_dnsZone.Origin)))
{
var responseCode = await _dnsZone.Update(ChangeRecords);
return query.CreateAnswerMessage(responseCode, ToString());
}

return query.CreateAnswerMessage(DnsResponseCode.Refused, ToString());
// Run the updates against the zone.
return _dnsZone.PerformZoneUpdates(records, query);
}), ToString());
}

/// <inheritdoc/>
Expand Down

0 comments on commit 32f874b

Please sign in to comment.