diff --git a/src/pdns-dhcp/Connections/ProtocolSocketIPEndPoint.cs b/src/pdns-dhcp/Connections/ProtocolSocketIPEndPoint.cs new file mode 100644 index 0000000..576f08b --- /dev/null +++ b/src/pdns-dhcp/Connections/ProtocolSocketIPEndPoint.cs @@ -0,0 +1,11 @@ +using System.Net; +using System.Net.Sockets; + +namespace pdns_dhcp.Connections; + +public class ProtocolSocketIPEndPoint(IPAddress address, int port, ProtocolType protocolType, SocketType socketType) : IPEndPoint(address, port) +{ + public ProtocolType ProtocolType => protocolType; + + public SocketType SocketType => socketType; +} diff --git a/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs b/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs deleted file mode 100644 index 0e0d424..0000000 --- a/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Net.Sockets; - -using Stl.Interception; - -namespace pdns_dhcp.PowerDns; - -public interface IPowerDnsFactory : IRequiresFullProxy -{ - PowerDnsStreamClient CreateClient(Stream stream); -} diff --git a/src/pdns-dhcp/PowerDns/PowerDnsHandler.cs b/src/pdns-dhcp/PowerDns/PowerDnsHandler.cs new file mode 100644 index 0000000..6134585 --- /dev/null +++ b/src/pdns-dhcp/PowerDns/PowerDnsHandler.cs @@ -0,0 +1,11 @@ +using Microsoft.AspNetCore.Connections; + +namespace pdns_dhcp.PowerDns; + +public class PowerDnsHandler : ConnectionHandler +{ + public override Task OnConnectedAsync(ConnectionContext connection) + { + return Task.CompletedTask; + } +} diff --git a/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs b/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs deleted file mode 100644 index 41efea6..0000000 --- a/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Text.Json; - -namespace pdns_dhcp.PowerDns; - -public class PowerDnsStreamClient : IDisposable -{ - private readonly Stream _stream; - private CancellationTokenSource _cts = new(); - private Task _task; - - public PowerDnsStreamClient(Stream stream) - { - _stream = stream; - } - - ~PowerDnsStreamClient() - { - DisposeCore(); - } - - public void Dispose() - { - _cts.Cancel(); - if (Interlocked.Exchange(ref _task, null!) is { } task) - { - task - .ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing) - .GetAwaiter().GetResult(); - } - - DisposeCore(); - - GC.SuppressFinalize(this); - } - - public void Start(CancellationToken stoppingToken) - { - var cts = CancellationTokenSource.CreateLinkedTokenSource(stoppingToken); - using var old = Interlocked.Exchange(ref _cts, cts); - old.Cancel(); - _task = Run(cts.Token); - } - - private void DisposeCore() - { - _cts.Dispose(); - _stream.Dispose(); - } - - private async Task Run(CancellationToken stoppingToken) - { - try - { - while (!stoppingToken.IsCancellationRequested) - { - switch (await JsonSerializer.DeserializeAsync(_stream, cancellationToken: stoppingToken).ConfigureAwait(false)) - { - case InitializeMethod init: - break; - - case LookupMethod lookup: - break; - - default: - break; - } - } - } - finally - { - if (Interlocked.Exchange(ref _task, null!) is not null) - { - Dispose(); - } - } - } -} diff --git a/src/pdns-dhcp/Program.cs b/src/pdns-dhcp/Program.cs index a79f932..04ccdbd 100644 --- a/src/pdns-dhcp/Program.cs +++ b/src/pdns-dhcp/Program.cs @@ -1,7 +1,14 @@ -using Microsoft.AspNetCore.Builder; +using System.Net; +using System.Net.Sockets; + +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Connections; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using pdns_dhcp.Connections; using pdns_dhcp.Kea; using pdns_dhcp.Options; using pdns_dhcp.PowerDns; @@ -10,6 +17,7 @@ using pdns_dhcp.Services; using Stl.Interception; var builder = WebApplication.CreateBuilder(args); + builder.Services.Configure(builder.Configuration.GetRequiredSection("Dhcp")); builder.Services.Configure(builder.Configuration.GetRequiredSection("PowerDns")); @@ -17,9 +25,50 @@ builder.Services.AddHostedService(); builder.Services.AddHostedService(); builder.Services.AddTypedFactory(); -builder.Services.AddTypedFactory(); builder.Services.AddTransient(); builder.Services.AddTransient(); +builder.WebHost.UseSockets(options => +{ + options.CreateBoundListenSocket = endpoint => + { + Socket socket; + switch (endpoint) + { + case ProtocolSocketIPEndPoint socketIp: + socket = new Socket(socketIp.AddressFamily, socketIp.SocketType, socketIp.ProtocolType); + + if (socketIp.Address.Equals(IPAddress.IPv6Any)) + { + socket.DualMode = true; + } + + break; + + default: + return SocketTransportOptions.CreateDefaultBoundListenSocket(endpoint); + } + + socket.Bind(endpoint); + return socket; + }; +}); + +builder.WebHost.UseKestrelCore(); +builder.WebHost.ConfigureKestrel((context, options) => +{ + if (context.Configuration.GetRequiredSection("PowerDns:Listener").Get() is { } pdnsOptions) + { + var path = PathEx.ExpandPath(pdnsOptions.Socket); + FileInfo file = new(path); + file.Directory!.Create(); + file.Delete(); + options.ListenUnixSocket(path, options => + { + options.UseConnectionHandler(); + }); + } +}); + builder.Build().Run(); diff --git a/src/pdns-dhcp/Services/PowerDnsBackend.cs b/src/pdns-dhcp/Services/PowerDnsBackend.cs index fed8a3b..5fd3f8d 100644 --- a/src/pdns-dhcp/Services/PowerDnsBackend.cs +++ b/src/pdns-dhcp/Services/PowerDnsBackend.cs @@ -1,27 +1,11 @@ -using System.Net.Sockets; - using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Options; - -using pdns_dhcp.Options; -using pdns_dhcp.PowerDns; namespace pdns_dhcp.Services; public class PowerDnsBackend : BackgroundService { - private readonly IPowerDnsFactory _factory; - private readonly Socket _socket; - - public PowerDnsBackend(IOptions options, IPowerDnsFactory socketFactory) + public PowerDnsBackend() { - _factory = socketFactory; - _socket = new(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified); - var path = PathEx.ExpandPath(options.Value.Listener.Socket); - FileInfo file = new(path); - file.Directory!.Create(); - file.Delete(); - _socket.Bind(new UnixDomainSocketEndPoint(path)); } ~PowerDnsBackend() @@ -29,14 +13,9 @@ public class PowerDnsBackend : BackgroundService DisposeCore(); } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) + protected override Task ExecuteAsync(CancellationToken stoppingToken) { - _socket.Listen(); - while (await _socket.AcceptAsync(stoppingToken) is { } client) - { - _factory.CreateClient(new NetworkStream(client, true)) - .Start(stoppingToken); - } + return Task.CompletedTask; } public override void Dispose() @@ -48,6 +27,5 @@ public class PowerDnsBackend : BackgroundService private void DisposeCore() { - _socket.Dispose(); } }