From 11a5549818acd613588254b8d640df856c5b6223 Mon Sep 17 00:00:00 2001 From: AliveDevil Date: Tue, 12 Dec 2023 00:59:57 +0100 Subject: [PATCH] PowerDns backend --- src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs | 2 -- src/pdns-dhcp/PowerDns/Methods.cs | 30 +++++++++++++++++++ src/pdns-dhcp/PowerDns/PowerDnsSocket.cs | 27 ----------------- .../PowerDns/PowerDnsStreamClient.cs | 26 +++++++++++++--- src/pdns-dhcp/PowerDns/Replies.cs | 10 +++++++ src/pdns-dhcp/Services/DhcpLeaseWatcher.cs | 1 - src/pdns-dhcp/Services/PowerDnsBackend.cs | 18 ++++++++--- 7 files changed, 76 insertions(+), 38 deletions(-) create mode 100644 src/pdns-dhcp/PowerDns/Methods.cs delete mode 100644 src/pdns-dhcp/PowerDns/PowerDnsSocket.cs create mode 100644 src/pdns-dhcp/PowerDns/Replies.cs diff --git a/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs b/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs index 7e31163..0e0d424 100644 --- a/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs +++ b/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs @@ -7,6 +7,4 @@ namespace pdns_dhcp.PowerDns; public interface IPowerDnsFactory : IRequiresFullProxy { PowerDnsStreamClient CreateClient(Stream stream); - - PowerDnsUnixSocket CreateUnixSocket(string socketPath); } diff --git a/src/pdns-dhcp/PowerDns/Methods.cs b/src/pdns-dhcp/PowerDns/Methods.cs new file mode 100644 index 0000000..fb77cd9 --- /dev/null +++ b/src/pdns-dhcp/PowerDns/Methods.cs @@ -0,0 +1,30 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace pdns_dhcp.PowerDns; + +public interface IMethod +{ + public abstract static string Method { get; } +} + +public abstract class Method where TSelf : Method, IMethod +{ + [JsonExtensionData] + public Dictionary ExtensionData { get; } = []; +} + +public abstract class Method(TParam parameters) : Method where TSelf : Method, IMethod +{ + public TParam Parameters => parameters; +} + +public class InitializeMethod : Method, IMethod +{ + public static string Method => "Initialize"; +} + +public class LookupMethod : Method, IMethod +{ + public static string Method => "Lookup"; +} diff --git a/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs b/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs deleted file mode 100644 index e94235e..0000000 --- a/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Net.Sockets; - -using Microsoft.Extensions.Hosting; - -namespace pdns_dhcp.PowerDns; - -public class PowerDnsUnixSocket : BackgroundService -{ - private readonly IPowerDnsFactory _factory; - private readonly Socket _socket; - - public PowerDnsUnixSocket(string socketPath, IPowerDnsFactory factory) - { - _factory = factory; - _socket = new(SocketType.Stream, ProtocolType.Unspecified); - _socket.Bind(new UnixDomainSocketEndPoint(socketPath)); - } - - protected override async Task ExecuteAsync(CancellationToken stoppingToken) - { - _socket.Listen(); - while (await _socket.AcceptAsync(stoppingToken) is { } client) - { - var instance = _factory.CreateClient(new NetworkStream(client, true)); - } - } -} diff --git a/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs b/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs index ca7d4b4..623a85a 100644 --- a/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs +++ b/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs @@ -1,8 +1,14 @@ +using System.Text.Json; + +using Stl.Async; + namespace pdns_dhcp.PowerDns; public class PowerDnsStreamClient : IDisposable { private readonly Stream _stream; + private CancellationTokenSource _cts = new(); + private Task _task; public PowerDnsStreamClient(Stream stream) { @@ -11,17 +17,29 @@ public class PowerDnsStreamClient : IDisposable ~PowerDnsStreamClient() { - Dispose(false); + Dispose(); } public void Dispose() { - Dispose(true); + using (_cts) + using (_stream) + { + _cts.Cancel(); + _task.GetAwaiter().GetResult(); + } GC.SuppressFinalize(this); } - private void Dispose(bool disposing) + public void Start(CancellationToken stoppingToken) { - _stream.Dispose(); + using var other = Interlocked.Exchange(ref _cts, CancellationTokenSource.CreateLinkedTokenSource(stoppingToken)); + _task = Run(_cts.Token); + other.Cancel(); + } + + private Task Run(CancellationToken stoppingToken) + { + return Task.CompletedTask; } } diff --git a/src/pdns-dhcp/PowerDns/Replies.cs b/src/pdns-dhcp/PowerDns/Replies.cs new file mode 100644 index 0000000..0d271cd --- /dev/null +++ b/src/pdns-dhcp/PowerDns/Replies.cs @@ -0,0 +1,10 @@ +namespace pdns_dhcp.PowerDns; + +public abstract class Reply; + +public abstract class Reply(T result) : Reply +{ + public T Result => result; +} + +public class BoolReply(bool result) : Reply(result); diff --git a/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs b/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs index ee8fb1e..5ea282a 100644 --- a/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs +++ b/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs @@ -3,7 +3,6 @@ using System.Collections.Immutable; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; -using pdns_dhcp.Kea; using pdns_dhcp.Options; namespace pdns_dhcp.Services; diff --git a/src/pdns-dhcp/Services/PowerDnsBackend.cs b/src/pdns-dhcp/Services/PowerDnsBackend.cs index 7739091..8f6f7ea 100644 --- a/src/pdns-dhcp/Services/PowerDnsBackend.cs +++ b/src/pdns-dhcp/Services/PowerDnsBackend.cs @@ -1,3 +1,5 @@ +using System.Net.Sockets; + using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; @@ -8,15 +10,23 @@ namespace pdns_dhcp.Services; public class PowerDnsBackend : BackgroundService { - private readonly PowerDnsOptions _options; + private readonly IPowerDnsFactory _factory; + private readonly Socket _socket; public PowerDnsBackend(IOptions options, IPowerDnsFactory socketFactory) { - _options = options.Value; + _factory = socketFactory; + _socket = new(SocketType.Stream, ProtocolType.Unknown); + _socket.Bind(new UnixDomainSocketEndPoint(options.Value.Listener.Socket)); } - protected override Task ExecuteAsync(CancellationToken stoppingToken) + protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - return Task.CompletedTask; + _socket.Listen(); + while (await _socket.AcceptAsync(stoppingToken) is { } client) + { + _factory.CreateClient(new NetworkStream(client, true)) + .Start(stoppingToken); + } } }