diff --git a/Apps/SplitHorizonApp/SimpleAddress.cs b/Apps/SplitHorizonApp/SimpleAddress.cs index 2baf21a5..41c8db9a 100644 --- a/Apps/SplitHorizonApp/SimpleAddress.cs +++ b/Apps/SplitHorizonApp/SimpleAddress.cs @@ -20,6 +20,7 @@ along with this program. If not, see . using DnsServerCore.ApplicationCommon; using Newtonsoft.Json; using System.Collections.Generic; +using System.IO; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; @@ -32,6 +33,12 @@ namespace SplitHorizon { public class SimpleAddress : IDnsApplication, IDnsAppRecordRequestHandler { + #region variables + + static IReadOnlyDictionary> _networks; + + #endregion + #region IDisposable public void Dispose() @@ -43,10 +50,54 @@ namespace SplitHorizon #region public - public Task InitializeAsync(IDnsServer dnsServer, string config) + public async Task InitializeAsync(IDnsServer dnsServer, string config) { - //no config needed - return Task.CompletedTask; + if (config.StartsWith('#')) + { + //replace old config with default config + config = @"{ + ""networks"": { + ""custom-networks"": [ + ""172.16.1.0/24"", + ""172.16.10.0/24"", + ""172.16.2.1"" + ] + } +} +"; + + await File.WriteAllTextAsync(Path.Combine(dnsServer.ApplicationFolder, "dnsApp.config"), config); + } + + dynamic jsonConfig = JsonConvert.DeserializeObject(config); + + dynamic jsonNetworks = jsonConfig.networks; + if (jsonNetworks is null) + { + _networks = new Dictionary>(1); + } + else + { + Dictionary> networks = new Dictionary>(); + + foreach (dynamic jsonProperty in jsonNetworks) + { + string networkName = jsonProperty.Name; + + dynamic jsonNetworkAddresses = jsonProperty.Value; + if (jsonNetworkAddresses is not null) + { + List networkAddresses = new List(); + + foreach (dynamic jsonNetworkAddress in jsonNetworkAddresses) + networkAddresses.Add(NetworkAddress.Parse(jsonNetworkAddress.Value)); + + networks.TryAdd(networkName, networkAddresses); + } + } + + _networks = networks; + } } public Task ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, DnsTransportProtocol protocol, bool isRecursionAllowed, string zoneName, uint appRecordTtl, string appRecordData) @@ -66,11 +117,27 @@ namespace SplitHorizon if ((name == "public") || (name == "private")) continue; - NetworkAddress networkAddress = NetworkAddress.Parse(name); - if (networkAddress.Contains(remoteEP.Address)) + if (_networks.TryGetValue(name, out List networkAddresses)) { - jsonAddresses = jsonProperty.Value; - break; + foreach (NetworkAddress networkAddress in networkAddresses) + { + if (networkAddress.Contains(remoteEP.Address)) + { + jsonAddresses = jsonProperty.Value; + break; + } + } + + if (jsonAddresses is not null) + break; + } + else if (NetworkAddress.TryParse(name, out NetworkAddress networkAddress)) + { + if (networkAddress.Contains(remoteEP.Address)) + { + jsonAddresses = jsonProperty.Value; + break; + } } } @@ -92,9 +159,7 @@ namespace SplitHorizon case DnsResourceRecordType.A: foreach (dynamic jsonAddress in jsonAddresses) { - IPAddress address = IPAddress.Parse(jsonAddress.Value); - - if (address.AddressFamily == AddressFamily.InterNetwork) + if (IPAddress.TryParse(jsonAddress.Value, out IPAddress address) && (address.AddressFamily == AddressFamily.InterNetwork)) answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecordData(address))); } break; @@ -102,9 +167,7 @@ namespace SplitHorizon case DnsResourceRecordType.AAAA: foreach (dynamic jsonAddress in jsonAddresses) { - IPAddress address = IPAddress.Parse(jsonAddress.Value); - - if (address.AddressFamily == AddressFamily.InterNetworkV6) + if (IPAddress.TryParse(jsonAddress.Value, out IPAddress address) && (address.AddressFamily == AddressFamily.InterNetworkV6)) answers.Add(new DnsResourceRecord(question.Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecordData(address))); } break; @@ -127,6 +190,9 @@ namespace SplitHorizon #region properties + internal static IReadOnlyDictionary> Networks + { get { return _networks; } } + public string Description { get { return "Returns A or AAAA records with different set of IP addresses for clients querying over public, private, or other specified networks."; } } @@ -143,6 +209,9 @@ namespace SplitHorizon ""192.168.1.1"", ""::1"" ], + ""custom-networks"": [ + ""172.16.1.1"", + ], ""10.0.0.0/8"": [ ""10.1.1.1"" ] diff --git a/Apps/SplitHorizonApp/SimpleCNAME.cs b/Apps/SplitHorizonApp/SimpleCNAME.cs index 413d6296..02868e37 100644 --- a/Apps/SplitHorizonApp/SimpleCNAME.cs +++ b/Apps/SplitHorizonApp/SimpleCNAME.cs @@ -1,6 +1,6 @@ /* Technitium DNS Server -Copyright (C) 2021 Shreyas Zare (shreyas@technitium.com) +Copyright (C) 2022 Shreyas Zare (shreyas@technitium.com) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ namespace SplitHorizon public Task InitializeAsync(IDnsServer dnsServer, string config) { - //no config needed + //SimpleAddress loads the shared config return Task.CompletedTask; } @@ -60,11 +60,27 @@ namespace SplitHorizon if ((name == "public") || (name == "private")) continue; - NetworkAddress networkAddress = NetworkAddress.Parse(name); - if (networkAddress.Contains(remoteEP.Address)) + if (SimpleAddress.Networks.TryGetValue(name, out List networkAddresses)) { - jsonCname = jsonProperty.Value; - break; + foreach (NetworkAddress networkAddress in networkAddresses) + { + if (networkAddress.Contains(remoteEP.Address)) + { + jsonCname = jsonProperty.Value; + break; + } + } + + if (jsonCname is not null) + break; + } + else if (NetworkAddress.TryParse(name, out NetworkAddress networkAddress)) + { + if (networkAddress.Contains(remoteEP.Address)) + { + jsonCname = jsonProperty.Value; + break; + } } } @@ -108,6 +124,7 @@ namespace SplitHorizon return @"{ ""public"": ""api.example.com"", ""private"": ""api.example.corp"", + ""custom-networks"": ""custom.example.corp"", ""10.0.0.0/8"": ""api.intranet.example.corp"" }"; } diff --git a/Apps/SplitHorizonApp/SplitHorizonApp.csproj b/Apps/SplitHorizonApp/SplitHorizonApp.csproj index bdffd165..a98ff5ca 100644 --- a/Apps/SplitHorizonApp/SplitHorizonApp.csproj +++ b/Apps/SplitHorizonApp/SplitHorizonApp.csproj @@ -3,7 +3,7 @@ net6.0 false - 3.0 + 3.1 Technitium Technitium DNS Server Shreyas Zare diff --git a/Apps/SplitHorizonApp/dnsApp.config b/Apps/SplitHorizonApp/dnsApp.config index 7a2450c3..e9fb633a 100644 --- a/Apps/SplitHorizonApp/dnsApp.config +++ b/Apps/SplitHorizonApp/dnsApp.config @@ -1 +1,9 @@ -#This app requires no config. \ No newline at end of file +{ + "networks": { + "custom-networks": [ + "172.16.1.0/24", + "172.16.10.0/24", + "172.16.2.1" + ] + } +}