Move DhcpLeaseChange to DnsRecord translation to DhcpQueueWorker

This commit is contained in:
Jöran Malek 2023-12-29 20:04:16 +01:00
parent c36c22d5ca
commit 1c1aadb69c
4 changed files with 60 additions and 56 deletions

View file

@ -40,37 +40,23 @@ public class DnsRepository
cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default); cancellationToken, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);
} }
public async ValueTask Record(DhcpLeaseChange leaseChange, CancellationToken cancellationToken = default) public async ValueTask Record(DnsRecord record, CancellationToken cancellationToken = default)
{ {
// just lock that thing. // just lock that thing.
using (await _recordLock.AcquireLockAsync(cancellationToken).ConfigureAwait(false)) using (await _recordLock.AcquireLockAsync(cancellationToken).ConfigureAwait(false))
{ {
RecordContinuation(leaseChange); RecordContinuation(record);
} }
void RecordContinuation(DhcpLeaseChange leaseChange) void RecordContinuation(DnsRecord record)
{ {
var search = Matches(leaseChange); var search = Matches(record);
bool lockEntered = false; bool lockEntered = false;
try try
{ {
lockEntered = _recordLock.TryEnterWriteLock(Timeout.Infinite); lockEntered = _recordLock.TryEnterWriteLock(Timeout.Infinite);
DnsRecordIdentifier identifier = leaseChange.Identifier switch
{
DhcpLeaseClientIdentifier clientId => new DnsRecordClientIdentifier(clientId.ClientId),
DhcpLeaseHWAddrIdentifier hwAddr => new DnsRecordHWAddrIdentifier(hwAddr.HWAddr),
_ => throw new ArgumentException(nameof(leaseChange.Identifier))
};
TimeSpan lifetime = leaseChange.Lifetime.TotalSeconds switch
{
<= 1800 => TimeSpan.FromSeconds(Lifetimes[0]),
>= 10800 => TimeSpan.FromSeconds(Lifetimes[1]),
{ } seconds => TimeSpan.FromSeconds(seconds / 3)
};
var record = new DnsRecord(leaseChange.Address, leaseChange.FQDN, identifier, lifetime);
if (search.First is { } node) if (search.First is { } node)
{ {
search.RemoveFirst(); search.RemoveFirst();
@ -102,25 +88,29 @@ public class DnsRepository
} }
} }
LinkedList<int> Matches(DhcpLeaseChange query) LinkedList<int> Matches(DnsRecord query)
{ {
LinkedList<int> list = []; LinkedList<int> list = [];
for (int i = 0; i < _records.Count; i++) for (int i = 0; i < _records.Count; i++)
{ {
var record = _records[i]; var record = _records[i];
if (record.RecordType != query.LeaseType) if (record.RecordType != query.RecordType)
{ {
continue; continue;
} }
switch ((record.Identifier, query.Identifier)) switch ((record.Identifier, query.Identifier))
{ {
case (DnsRecordClientIdentifier recordClientId, DhcpLeaseClientIdentifier queryClientId) case (
when StringComparer.InvariantCultureIgnoreCase.Equals(recordClientId.ClientId, queryClientId.ClientId): DnsRecordClientIdentifier { ClientId: { } recordClientId },
DnsRecordClientIdentifier { ClientId: { } queryClientId }
) when StringComparer.InvariantCultureIgnoreCase.Equals(recordClientId, queryClientId):
case (DnsRecordHWAddrIdentifier recordHWAddr, DhcpLeaseHWAddrIdentifier queryHWAddr) case (
when EqualityComparer<PhysicalAddress>.Default.Equals(recordHWAddr.HWAddr, queryHWAddr.HWAddr): DnsRecordHWAddrIdentifier { HWAddr: { } recordHWAddr },
DnsRecordHWAddrIdentifier { HWAddr: { } queryHWAddr }
) when EqualityComparer<PhysicalAddress>.Default.Equals(recordHWAddr, queryHWAddr):
list.AddLast(i); list.AddLast(i);
continue; continue;

View file

@ -24,7 +24,7 @@ builder.Services.Configure<DhcpOptions>(builder.Configuration.GetRequiredSection
builder.Services.Configure<PowerDnsOptions>(builder.Configuration.GetRequiredSection("PowerDns")); builder.Services.Configure<PowerDnsOptions>(builder.Configuration.GetRequiredSection("PowerDns"));
builder.Services.AddHostedService<DhcpWatcher>(); builder.Services.AddHostedService<DhcpWatcher>();
builder.Services.AddHostedService<DnsQueueWorker>(); builder.Services.AddHostedService<DhcpQueueWorker>();
builder.Services.AddSingleton<DhcpLeaseQueue>(); builder.Services.AddSingleton<DhcpLeaseQueue>();
builder.Services.AddSingleton<DnsRepository>(); builder.Services.AddSingleton<DnsRepository>();

View file

@ -0,0 +1,45 @@
using System.Threading.Channels;
using Microsoft.Extensions.Hosting;
using pdns_dhcp.Dhcp;
using pdns_dhcp.Dns;
namespace pdns_dhcp.Services;
public class DhcpQueueWorker : BackgroundService
{
private readonly ChannelReader<DhcpLeaseChange> _channelReader;
private readonly DnsRepository _repository;
public DhcpQueueWorker(DhcpLeaseQueue queue, DnsRepository repository)
{
_channelReader = queue.Reader;
_repository = repository;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (await _channelReader.WaitToReadAsync(stoppingToken).ConfigureAwait(false))
{
while (_channelReader.TryRead(out var lease))
{
DnsRecordIdentifier identifier = lease.Identifier switch
{
DhcpLeaseClientIdentifier clientId => new DnsRecordClientIdentifier(clientId.ClientId),
DhcpLeaseHWAddrIdentifier hwAddr => new DnsRecordHWAddrIdentifier(hwAddr.HWAddr),
_ => throw new ArgumentException(nameof(lease.Identifier))
};
TimeSpan lifetime = lease.Lifetime.TotalSeconds switch
{
<= 1800 => TimeSpan.FromSeconds(600),
>= 10800 => TimeSpan.FromSeconds(3600),
{ } seconds => TimeSpan.FromSeconds(seconds / 3)
};
await _repository.Record(new DnsRecord(lease.Address, lease.FQDN, identifier, lifetime), stoppingToken).ConfigureAwait(false);
}
}
}
}

View file

@ -1,31 +0,0 @@
using System.Threading.Channels;
using Microsoft.Extensions.Hosting;
using pdns_dhcp.Dhcp;
using pdns_dhcp.Dns;
namespace pdns_dhcp.Services;
public class DnsQueueWorker : BackgroundService
{
private readonly ChannelReader<DhcpLeaseChange> _channelReader;
private readonly DnsRepository _repository;
public DnsQueueWorker(DhcpLeaseQueue queue, DnsRepository repository)
{
_channelReader = queue.Reader;
_repository = repository;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (await _channelReader.WaitToReadAsync(stoppingToken).ConfigureAwait(false))
{
while (_channelReader.TryRead(out var lease))
{
await _repository.Record(default, stoppingToken).ConfigureAwait(false);
}
}
}
}