Port to Kestrel
This commit is contained in:
parent
7f9dc36473
commit
5c9db5d5f2
6 changed files with 76 additions and 114 deletions
11
src/pdns-dhcp/Connections/ProtocolSocketIPEndPoint.cs
Normal file
11
src/pdns-dhcp/Connections/ProtocolSocketIPEndPoint.cs
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
using System.Net.Sockets;
|
||||
|
||||
using Stl.Interception;
|
||||
|
||||
namespace pdns_dhcp.PowerDns;
|
||||
|
||||
public interface IPowerDnsFactory : IRequiresFullProxy
|
||||
{
|
||||
PowerDnsStreamClient CreateClient(Stream stream);
|
||||
}
|
||||
11
src/pdns-dhcp/PowerDns/PowerDnsHandler.cs
Normal file
11
src/pdns-dhcp/PowerDns/PowerDnsHandler.cs
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<Method>(_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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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<DhcpOptions>(builder.Configuration.GetRequiredSection("Dhcp"));
|
||||
builder.Services.Configure<PowerDnsOptions>(builder.Configuration.GetRequiredSection("PowerDns"));
|
||||
|
||||
|
|
@ -17,9 +25,50 @@ builder.Services.AddHostedService<DhcpLeaseWatcher>();
|
|||
builder.Services.AddHostedService<PowerDnsBackend>();
|
||||
|
||||
builder.Services.AddTypedFactory<IDhcpLeaseWatcherFactory>();
|
||||
builder.Services.AddTypedFactory<IPowerDnsFactory>();
|
||||
|
||||
builder.Services.AddTransient<KeaDhcp4LeaseHandler>();
|
||||
builder.Services.AddTransient<KeaDhcp6LeaseHandler>();
|
||||
|
||||
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<PowerDnsListenerOptions>() is { } pdnsOptions)
|
||||
{
|
||||
var path = PathEx.ExpandPath(pdnsOptions.Socket);
|
||||
FileInfo file = new(path);
|
||||
file.Directory!.Create();
|
||||
file.Delete();
|
||||
options.ListenUnixSocket(path, options =>
|
||||
{
|
||||
options.UseConnectionHandler<PowerDnsHandler>();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
builder.Build().Run();
|
||||
|
|
|
|||
|
|
@ -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<PowerDnsOptions> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue