From ec31039eede73aca4945ac30e5eda636904d63f6 Mon Sep 17 00:00:00 2001 From: AliveDevil Date: Thu, 16 Nov 2023 00:38:35 +0100 Subject: [PATCH] Work on DHCP --- ext/dhcp4.leases | 6 +++++ ext/dhcp6.leases | 7 +++++ src/pdns-dhcp/Kea/KeaDhcp4Lease.cs | 17 ++++++++++++ src/pdns-dhcp/Kea/KeaDhcp6Lease.cs | 23 ++++++++++++++++ src/pdns-dhcp/Kea/KeaLeaseWatcher.cs | 5 ++++ src/pdns-dhcp/Kea/LeaseType.cs | 9 +++++++ src/pdns-dhcp/Options/DhcpOptions.cs | 6 +++++ src/pdns-dhcp/Options/KeaDhcpOptions.cs | 2 +- src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs | 12 +++++++++ src/pdns-dhcp/PowerDns/PowerDnsSocket.cs | 22 ++++++++++++--- .../PowerDns/PowerDnsStreamClient.cs | 27 +++++++++++++++++++ src/pdns-dhcp/PowerDns/SocketFactory.cs | 8 ------ src/pdns-dhcp/Program.cs | 9 ++++--- src/pdns-dhcp/Services/DhcpLeaseWatcher.cs | 9 ++----- src/pdns-dhcp/Services/PowerDnsBackend.cs | 14 ++++++++++ src/pdns-dhcp/appsettings.Development.json | 17 ++++++++++++ src/pdns-dhcp/appsettings.json | 14 +++++----- src/pdns-dhcp/pdns-dhcp.csproj | 4 +++ 18 files changed, 182 insertions(+), 29 deletions(-) create mode 100644 ext/dhcp4.leases create mode 100644 ext/dhcp6.leases create mode 100644 src/pdns-dhcp/Kea/KeaDhcp4Lease.cs create mode 100644 src/pdns-dhcp/Kea/KeaDhcp6Lease.cs create mode 100644 src/pdns-dhcp/Kea/KeaLeaseWatcher.cs create mode 100644 src/pdns-dhcp/Kea/LeaseType.cs create mode 100644 src/pdns-dhcp/Options/DhcpOptions.cs create mode 100644 src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs create mode 100644 src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs delete mode 100644 src/pdns-dhcp/PowerDns/SocketFactory.cs create mode 100644 src/pdns-dhcp/appsettings.Development.json diff --git a/ext/dhcp4.leases b/ext/dhcp4.leases new file mode 100644 index 0000000..7b9ba23 --- /dev/null +++ b/ext/dhcp4.leases @@ -0,0 +1,6 @@ +address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context +192.0.2.1,06:07:08:09:0a:bc,,200,200,8,1,1,host.example.com,0, +192.0.2.2,,,200,200,8,1,1,host.example.com,0, +192.0.2.3,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,0,0,,1,{ "foobar": true } +192.0.2.4,,11:22:33:44:55:66,200,200,8,1,1,host.example.com,0, +192.0.2.5,,,200,200,8,1,1,,1, diff --git a/ext/dhcp6.leases b/ext/dhcp6.leases new file mode 100644 index 0000000..f51bc14 --- /dev/null +++ b/ext/dhcp6.leases @@ -0,0 +1,7 @@ +address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,state,user_context,hwtype,hwaddr_source,pool_id +2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0 +2001:db8:1::1,,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0 +2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,0,8,0,0,0,,,1,,1,0,0 +3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,0,200,8,0,2,16,64,0,0,,,1,{ "foobar": true },,1,0,0 +2001:db8:1::2,00:00:00,200,200,8,100,0,7,0,1,1,host.example.com,,0,,1,0,0 +2001:db8:1::3,00:00:00,200,200,8,100,0,7,0,1,1,host.example.com,,1,,1,0,0 diff --git a/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs b/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs new file mode 100644 index 0000000..fb9ac95 --- /dev/null +++ b/src/pdns-dhcp/Kea/KeaDhcp4Lease.cs @@ -0,0 +1,17 @@ +namespace pdns_dhcp.Kea; + +// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file4.h +public record struct KeaDhcp4Lease( + string Address, + string HWAddr, + string? ClientId, + UInt32 ValidLifetime, + UInt64 Expire, + string SubnetId, + byte FqdnFwd, + byte FqdnRev, + string Hostname, + UInt32 State, + string UserContext, + UInt32 PoolId +); diff --git a/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs b/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs new file mode 100644 index 0000000..e35ddc5 --- /dev/null +++ b/src/pdns-dhcp/Kea/KeaDhcp6Lease.cs @@ -0,0 +1,23 @@ +namespace pdns_dhcp.Kea; + +// ref: https://github.com/isc-projects/kea/blob/Kea-2.5.3/src/lib/dhcpsrv/csv_lease_file6.h +public record struct KeaDhcp6Lease( + string Address, + string DUId, + UInt32 ValidLifetime, + UInt64 Expire, + string SubnetId, + UInt32 PrefLifetime, + LeaseType LeaseType, + UInt32 IAId, + Byte PrefixLen, + byte FqdnFwd, + byte FqdnRev, + string Hostname, + string HWAddr, + UInt32 State, + string UserContext, + UInt16? HWType, + UInt32? HWAddrSource, + UInt32 PoolId +); diff --git a/src/pdns-dhcp/Kea/KeaLeaseWatcher.cs b/src/pdns-dhcp/Kea/KeaLeaseWatcher.cs new file mode 100644 index 0000000..f66b027 --- /dev/null +++ b/src/pdns-dhcp/Kea/KeaLeaseWatcher.cs @@ -0,0 +1,5 @@ +namespace pdns_dhcp.Kea; + +public class KeaLeaseWatcher +{ +} diff --git a/src/pdns-dhcp/Kea/LeaseType.cs b/src/pdns-dhcp/Kea/LeaseType.cs new file mode 100644 index 0000000..e771d03 --- /dev/null +++ b/src/pdns-dhcp/Kea/LeaseType.cs @@ -0,0 +1,9 @@ +namespace pdns_dhcp.Kea; + +public enum LeaseType : byte +{ + NonTempraryIPv6 = 0, + TemporaryIPv6 = 1, + IPv6Prefix = 2, + IPv4 = 3 +} diff --git a/src/pdns-dhcp/Options/DhcpOptions.cs b/src/pdns-dhcp/Options/DhcpOptions.cs new file mode 100644 index 0000000..dcc38d0 --- /dev/null +++ b/src/pdns-dhcp/Options/DhcpOptions.cs @@ -0,0 +1,6 @@ +namespace pdns_dhcp.Options; + +public class DhcpOptions +{ + public KeaDhcpOptions? Kea { get; set; } +} diff --git a/src/pdns-dhcp/Options/KeaDhcpOptions.cs b/src/pdns-dhcp/Options/KeaDhcpOptions.cs index 0e297ba..d7213c7 100644 --- a/src/pdns-dhcp/Options/KeaDhcpOptions.cs +++ b/src/pdns-dhcp/Options/KeaDhcpOptions.cs @@ -7,4 +7,4 @@ public class KeaDhcpOptions public KeaDhcpServerOptions? Dhcp6 { get; set; } } -public record class KeaDhcpServerOptions(FileInfo Leases); +public record class KeaDhcpServerOptions(string Leases); diff --git a/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs b/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs new file mode 100644 index 0000000..7e31163 --- /dev/null +++ b/src/pdns-dhcp/PowerDns/IPowerDnsFactory.cs @@ -0,0 +1,12 @@ +using System.Net.Sockets; + +using Stl.Interception; + +namespace pdns_dhcp.PowerDns; + +public interface IPowerDnsFactory : IRequiresFullProxy +{ + PowerDnsStreamClient CreateClient(Stream stream); + + PowerDnsUnixSocket CreateUnixSocket(string socketPath); +} diff --git a/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs b/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs index 1607b51..e94235e 100644 --- a/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs +++ b/src/pdns-dhcp/PowerDns/PowerDnsSocket.cs @@ -1,11 +1,27 @@ using System.Net.Sockets; +using Microsoft.Extensions.Hosting; + namespace pdns_dhcp.PowerDns; -public class PowerDnsSocket +public class PowerDnsUnixSocket : BackgroundService { - public PowerDnsSocket() + 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 new file mode 100644 index 0000000..ca7d4b4 --- /dev/null +++ b/src/pdns-dhcp/PowerDns/PowerDnsStreamClient.cs @@ -0,0 +1,27 @@ +namespace pdns_dhcp.PowerDns; + +public class PowerDnsStreamClient : IDisposable +{ + private readonly Stream _stream; + + public PowerDnsStreamClient(Stream stream) + { + _stream = stream; + } + + ~PowerDnsStreamClient() + { + Dispose(false); + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose(bool disposing) + { + _stream.Dispose(); + } +} diff --git a/src/pdns-dhcp/PowerDns/SocketFactory.cs b/src/pdns-dhcp/PowerDns/SocketFactory.cs deleted file mode 100644 index 4718b52..0000000 --- a/src/pdns-dhcp/PowerDns/SocketFactory.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Stl.Interception; - -namespace pdns_dhcp.PowerDns; - -public interface SocketFactory : IRequiresFullProxy -{ - PowerDnsSocket Create(); -} diff --git a/src/pdns-dhcp/Program.cs b/src/pdns-dhcp/Program.cs index 2dc47ba..7bcfb17 100644 --- a/src/pdns-dhcp/Program.cs +++ b/src/pdns-dhcp/Program.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using pdns_dhcp.Options; @@ -8,12 +9,12 @@ using pdns_dhcp.Services; using Stl.Interception; var builder = Host.CreateApplicationBuilder(args); -builder.Services.Configure(builder.Configuration.GetSection("KeaDhcp")); -builder.Services.Configure(builder.Configuration.GetSection("PowerDns")); +builder.Services.Configure(builder.Configuration.GetRequiredSection("Dhcp")); +builder.Services.Configure(builder.Configuration.GetRequiredSection("PowerDns")); builder.Services.AddHostedService(); builder.Services.AddHostedService(); -builder.Services.AddTypedFactory(); +builder.Services.AddTypedFactory(); builder.Build().Run(); diff --git a/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs b/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs index ac0e778..a4a7bb0 100644 --- a/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs +++ b/src/pdns-dhcp/Services/DhcpLeaseWatcher.cs @@ -1,20 +1,15 @@ +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; using pdns_dhcp.Options; -using pdns_dhcp.PowerDns; namespace pdns_dhcp.Services; public class DhcpLeaseWatcher : IHostedService { - private readonly PowerDnsOptions _options; - private readonly PowerDnsSocket _socket; - - public DhcpLeaseWatcher(IOptions options, SocketFactory factory) + public DhcpLeaseWatcher(IOptions options) { - _options = options.Value; - _socket = factory.Create(); } public Task StartAsync(CancellationToken cancellationToken) diff --git a/src/pdns-dhcp/Services/PowerDnsBackend.cs b/src/pdns-dhcp/Services/PowerDnsBackend.cs index 6568702..a4e0cb3 100644 --- a/src/pdns-dhcp/Services/PowerDnsBackend.cs +++ b/src/pdns-dhcp/Services/PowerDnsBackend.cs @@ -1,9 +1,23 @@ +using System.Net.Sockets; + +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Options; + +using pdns_dhcp.Options; +using pdns_dhcp.PowerDns; namespace pdns_dhcp.Services; public class PowerDnsBackend : IHostedService { + private readonly PowerDnsOptions _options; + + public PowerDnsBackend(IOptions options, IPowerDnsFactory socketFactory) + { + _options = options.Value; + } + public Task StartAsync(CancellationToken cancellationToken) { throw new NotImplementedException(); diff --git a/src/pdns-dhcp/appsettings.Development.json b/src/pdns-dhcp/appsettings.Development.json new file mode 100644 index 0000000..c9bc257 --- /dev/null +++ b/src/pdns-dhcp/appsettings.Development.json @@ -0,0 +1,17 @@ +{ + "PowerDns": { + "Listener": { + "Socket": "/run/pdns-dhcp/pdns.sock" + } + }, + "Dhcp": { + "Kea": { + "Dhcp4": { + "Leases": "../../ext/kea/dhcp4.leases" + }, + "DHcp6": { + "Leases": "../..ext/kea/dhcp4.leases" + } + } + } +} \ No newline at end of file diff --git a/src/pdns-dhcp/appsettings.json b/src/pdns-dhcp/appsettings.json index d6659c2..fa3c07f 100644 --- a/src/pdns-dhcp/appsettings.json +++ b/src/pdns-dhcp/appsettings.json @@ -4,12 +4,14 @@ "Socket": "/run/pdns-dhcp/pdns.sock" } }, - "KeaDhcp": { - "Dhcp4": { - "Leases": "/var/lib/kea/dhcp4.leases" - }, - "Dhcp6": { - "Leases": "/var/lib/kea/dhcp6.leases" + "Dhcp": { + "Kea": { + "Dhcp4": { + "Leases": "/var/lib/kea/dhcp4.leases" + }, + "DHcp6": { + "Leases": "/var/lib/kea/dhcp6.leases" + } } } } \ No newline at end of file diff --git a/src/pdns-dhcp/pdns-dhcp.csproj b/src/pdns-dhcp/pdns-dhcp.csproj index 6af24a5..c89ab62 100644 --- a/src/pdns-dhcp/pdns-dhcp.csproj +++ b/src/pdns-dhcp/pdns-dhcp.csproj @@ -6,10 +6,14 @@ pdns_dhcp enable enable + true + true + +