diff --git a/DnsServerCore/DnsWebService.cs b/DnsServerCore/DnsWebService.cs
index a37de8ca..ff20f45c 100644
--- a/DnsServerCore/DnsWebService.cs
+++ b/DnsServerCore/DnsWebService.cs
@@ -20,7 +20,6 @@ along with this program. If not, see .
using DnsServerCore.Auth;
using DnsServerCore.Dhcp;
using DnsServerCore.Dns;
-using DnsServerCore.Dns.ResourceRecords;
using DnsServerCore.Dns.ZoneManagers;
using DnsServerCore.Dns.Zones;
using Microsoft.AspNetCore.Builder;
@@ -37,7 +36,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
-using System.Net.Http;
+using System.Net.Quic;
using System.Net.Sockets;
using System.Reflection;
using System.Security.Cryptography;
@@ -62,23 +61,27 @@ namespace DnsServerCore
internal readonly Version _currentVersion;
readonly string _appFolder;
internal readonly string _configFolder;
- readonly Uri _updateCheckUri;
internal readonly LogManager _log;
internal readonly AuthManager _authManager;
- internal readonly WebServiceSettingsApi _settingsApi;
- internal readonly WebServiceAuthApi _authApi;
- internal readonly WebServiceDashboardApi _dashboardApi;
+ readonly WebServiceApi _api;
+ readonly WebServiceDashboardApi _dashboardApi;
internal readonly WebServiceZonesApi _zonesApi;
- internal readonly WebServiceOtherZonesApi _otherZonesApi;
+ readonly WebServiceOtherZonesApi _otherZonesApi;
internal readonly WebServiceAppsApi _appsApi;
- internal readonly WebServiceDhcpApi _dhcpApi;
- internal readonly WebServiceLogsApi _logsApi;
+ readonly WebServiceSettingsApi _settingsApi;
+ readonly WebServiceDhcpApi _dhcpApi;
+ readonly WebServiceAuthApi _authApi;
+ readonly WebServiceLogsApi _logsApi;
- internal DnsServer _dnsServer;
- internal DhcpServer _dhcpServer;
+ WebApplication _webService;
+ X509Certificate2 _webServiceTlsCertificate;
+ DnsServer _dnsServer;
+ DhcpServer _dhcpServer;
+
+ //web service
internal IReadOnlyList _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any, IPAddress.IPv6Any };
internal int _webServiceHttpPort = 5380;
internal int _webServiceTlsPort = 53443;
@@ -87,16 +90,16 @@ namespace DnsServerCore
internal bool _webServiceUseSelfSignedTlsCertificate;
internal string _webServiceTlsCertificatePath;
internal string _webServiceTlsCertificatePassword;
- internal DateTime _webServiceTlsCertificateLastModifiedOn;
-
- WebApplication _webService;
- X509Certificate2 _webServiceTlsCertificate;
- readonly IndependentTaskScheduler _webServiceTaskScheduler = new IndependentTaskScheduler(ThreadPriority.AboveNormal);
+ DateTime _webServiceTlsCertificateLastModifiedOn;
+ //optional protocols
internal string _dnsTlsCertificatePath;
internal string _dnsTlsCertificatePassword;
DateTime _dnsTlsCertificateLastModifiedOn;
+ //cache
+ internal bool _saveCache;
+
Timer _tlsCertificateUpdateTimer;
const int TLS_CERTIFICATE_UPDATE_TIMER_INITIAL_INTERVAL = 60000;
const int TLS_CERTIFICATE_UPDATE_TIMER_INTERVAL = 60000;
@@ -119,21 +122,20 @@ namespace DnsServerCore
else
_configFolder = configFolder;
- _updateCheckUri = updateCheckUri;
-
Directory.CreateDirectory(_configFolder);
Directory.CreateDirectory(Path.Combine(_configFolder, "blocklists"));
_log = new LogManager(_configFolder);
_authManager = new AuthManager(_configFolder, _log);
- _settingsApi = new WebServiceSettingsApi(this);
- _authApi = new WebServiceAuthApi(this);
+ _api = new WebServiceApi(this, updateCheckUri);
_dashboardApi = new WebServiceDashboardApi(this);
_zonesApi = new WebServiceZonesApi(this);
_otherZonesApi = new WebServiceOtherZonesApi(this);
_appsApi = new WebServiceAppsApi(this, appStoreUri);
+ _settingsApi = new WebServiceSettingsApi(this);
_dhcpApi = new WebServiceDhcpApi(this);
+ _authApi = new WebServiceAuthApi(this);
_logsApi = new WebServiceLogsApi(this);
}
@@ -150,17 +152,11 @@ namespace DnsServerCore
await StopAsync();
- if (_settingsApi is not null)
- _settingsApi.Dispose();
-
if (_appsApi is not null)
_appsApi.Dispose();
- if (_dnsServer is not null)
- _dnsServer.Dispose();
-
- if (_dhcpServer is not null)
- _dhcpServer.Dispose();
+ if (_settingsApi is not null)
+ _settingsApi.Dispose();
if (_authManager is not null)
_authManager.Dispose();
@@ -178,11 +174,59 @@ namespace DnsServerCore
#endregion
- #region private
+ #region server version
+
+ internal string GetServerVersion()
+ {
+ return GetCleanVersion(_currentVersion);
+ }
+
+ internal static string GetCleanVersion(Version version)
+ {
+ string strVersion = version.Major + "." + version.Minor;
+
+ if (version.Build > 0)
+ strVersion += "." + version.Build;
+
+ if (version.Revision > 0)
+ strVersion += "." + version.Revision;
+
+ return strVersion;
+ }
+
+ #endregion
#region web service
- internal async Task StartWebServiceAsync()
+ internal async Task TryStartWebServiceAsync()
+ {
+ try
+ {
+ _webServiceLocalAddresses = DnsServer.GetValidKestralLocalAddresses(_webServiceLocalAddresses);
+ await StartWebServiceAsync();
+ }
+ catch (Exception ex)
+ {
+ _log.Write("Web Service failed to start: " + ex.ToString());
+ _log.Write("Attempting to start Web Service on ANY (0.0.0.0) fallback address...");
+
+ try
+ {
+ _webServiceLocalAddresses = new IPAddress[] { IPAddress.Any };
+ await StartWebServiceAsync();
+ }
+ catch (Exception ex2)
+ {
+ _log.Write("Web Service failed to start: " + ex2.ToString());
+ _log.Write("Attempting to start Web Service on loopback (127.0.0.1) fallback address...");
+
+ _webServiceLocalAddresses = new IPAddress[] { IPAddress.Loopback };
+ await StartWebServiceAsync();
+ }
+ }
+ }
+
+ private async Task StartWebServiceAsync()
{
WebApplicationBuilder builder = WebApplication.CreateBuilder();
@@ -247,14 +291,41 @@ namespace DnsServerCore
ConfigureWebServiceRoutes();
- await _webService.StartAsync();
+ try
+ {
+ await _webService.StartAsync();
- _log.Write(new IPEndPoint(IPAddress.Any, _webServiceHttpPort), "Web Service was started successfully.");
+ foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
+ {
+ _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service was bound successfully.");
+
+ if (_webServiceEnableTls && (_webServiceTlsCertificate is not null))
+ _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service was bound successfully.");
+ }
+ }
+ catch
+ {
+ await StopWebServiceAsync();
+
+ foreach (IPAddress webServiceLocalAddress in _webServiceLocalAddresses)
+ {
+ _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Http", "Web Service failed to bind.");
+
+ if (_webServiceEnableTls && (_webServiceTlsCertificate is not null))
+ _log?.Write(new IPEndPoint(webServiceLocalAddress, _webServiceHttpPort), "Https", "Web Service failed to bind.");
+ }
+
+ throw;
+ }
}
internal async Task StopWebServiceAsync()
{
- await _webService.DisposeAsync();
+ if (_webService is not null)
+ {
+ await _webService.DisposeAsync();
+ _webService = null;
+ }
}
private void ConfigureWebServiceRoutes()
@@ -266,134 +337,134 @@ namespace DnsServerCore
_webService.UseRouting();
//user auth
- _webService.MapGet("/api/user/login", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.Standard); });
- _webService.MapGet("/api/user/createToken", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.ApiToken); });
- _webService.MapGet("/api/user/logout", _authApi.Logout);
+ _webService.MapGetAndPost("/api/user/login", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.Standard); });
+ _webService.MapGetAndPost("/api/user/createToken", delegate (HttpContext context) { return _authApi.LoginAsync(context, UserSessionType.ApiToken); });
+ _webService.MapGetAndPost("/api/user/logout", _authApi.Logout);
//user
- _webService.MapGet("/api/user/session/get", _authApi.GetCurrentSessionDetails);
- _webService.MapGet("/api/user/session/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, false); });
- _webService.MapGet("/api/user/changePassword", _authApi.ChangePassword);
- _webService.MapGet("/api/user/profile/get", _authApi.GetProfile);
- _webService.MapGet("/api/user/profile/set", _authApi.SetProfile);
- _webService.MapGet("/api/user/checkForUpdate", CheckForUpdateAsync);
+ _webService.MapGetAndPost("/api/user/session/get", _authApi.GetCurrentSessionDetails);
+ _webService.MapGetAndPost("/api/user/session/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, false); });
+ _webService.MapGetAndPost("/api/user/changePassword", _authApi.ChangePassword);
+ _webService.MapGetAndPost("/api/user/profile/get", _authApi.GetProfile);
+ _webService.MapGetAndPost("/api/user/profile/set", _authApi.SetProfile);
+ _webService.MapGetAndPost("/api/user/checkForUpdate", _api.CheckForUpdateAsync);
//dashboard
- _webService.MapGet("/api/dashboard/stats/get", _dashboardApi.GetStats);
- _webService.MapGet("/api/dashboard/stats/getTop", _dashboardApi.GetTopStats);
- _webService.MapGet("/api/dashboard/stats/deleteAll", _logsApi.DeleteAllStats);
+ _webService.MapGetAndPost("/api/dashboard/stats/get", _dashboardApi.GetStats);
+ _webService.MapGetAndPost("/api/dashboard/stats/getTop", _dashboardApi.GetTopStats);
+ _webService.MapGetAndPost("/api/dashboard/stats/deleteAll", _logsApi.DeleteAllStats);
//zones
- _webService.MapGet("/api/zones/list", _zonesApi.ListZones);
- _webService.MapGet("/api/zones/create", _zonesApi.CreateZoneAsync);
- _webService.MapGet("/api/zones/enable", _zonesApi.EnableZone);
- _webService.MapGet("/api/zones/disable", _zonesApi.DisableZone);
- _webService.MapGet("/api/zones/delete", _zonesApi.DeleteZone);
- _webService.MapGet("/api/zones/resync", _zonesApi.ResyncZone);
- _webService.MapGet("/api/zones/options/get", _zonesApi.GetZoneOptions);
- _webService.MapGet("/api/zones/options/set", _zonesApi.SetZoneOptions);
- _webService.MapGet("/api/zones/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Zones); });
- _webService.MapGet("/api/zones/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Zones); });
- _webService.MapGet("/api/zones/dnssec/sign", _zonesApi.SignPrimaryZone);
- _webService.MapGet("/api/zones/dnssec/unsign", _zonesApi.UnsignPrimaryZone);
- _webService.MapGet("/api/zones/dnssec/properties/get", _zonesApi.GetPrimaryZoneDnssecProperties);
- _webService.MapGet("/api/zones/dnssec/properties/convertToNSEC", _zonesApi.ConvertPrimaryZoneToNSEC);
- _webService.MapGet("/api/zones/dnssec/properties/convertToNSEC3", _zonesApi.ConvertPrimaryZoneToNSEC3);
- _webService.MapGet("/api/zones/dnssec/properties/updateNSEC3Params", _zonesApi.UpdatePrimaryZoneNSEC3Parameters);
- _webService.MapGet("/api/zones/dnssec/properties/updateDnsKeyTtl", _zonesApi.UpdatePrimaryZoneDnssecDnsKeyTtl);
- _webService.MapGet("/api/zones/dnssec/properties/generatePrivateKey", _zonesApi.GenerateAndAddPrimaryZoneDnssecPrivateKey);
- _webService.MapGet("/api/zones/dnssec/properties/updatePrivateKey", _zonesApi.UpdatePrimaryZoneDnssecPrivateKey);
- _webService.MapGet("/api/zones/dnssec/properties/deletePrivateKey", _zonesApi.DeletePrimaryZoneDnssecPrivateKey);
- _webService.MapGet("/api/zones/dnssec/properties/publishAllPrivateKeys", _zonesApi.PublishAllGeneratedPrimaryZoneDnssecPrivateKeys);
- _webService.MapGet("/api/zones/dnssec/properties/rolloverDnsKey", _zonesApi.RolloverPrimaryZoneDnsKey);
- _webService.MapGet("/api/zones/dnssec/properties/retireDnsKey", _zonesApi.RetirePrimaryZoneDnsKey);
- _webService.MapGet("/api/zones/records/add", _zonesApi.AddRecord);
- _webService.MapGet("/api/zones/records/get", _zonesApi.GetRecords);
- _webService.MapGet("/api/zones/records/update", _zonesApi.UpdateRecord);
- _webService.MapGet("/api/zones/records/delete", _zonesApi.DeleteRecord);
+ _webService.MapGetAndPost("/api/zones/list", _zonesApi.ListZones);
+ _webService.MapGetAndPost("/api/zones/create", _zonesApi.CreateZoneAsync);
+ _webService.MapGetAndPost("/api/zones/enable", _zonesApi.EnableZone);
+ _webService.MapGetAndPost("/api/zones/disable", _zonesApi.DisableZone);
+ _webService.MapGetAndPost("/api/zones/delete", _zonesApi.DeleteZone);
+ _webService.MapGetAndPost("/api/zones/resync", _zonesApi.ResyncZone);
+ _webService.MapGetAndPost("/api/zones/options/get", _zonesApi.GetZoneOptions);
+ _webService.MapGetAndPost("/api/zones/options/set", _zonesApi.SetZoneOptions);
+ _webService.MapGetAndPost("/api/zones/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Zones); });
+ _webService.MapGetAndPost("/api/zones/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Zones); });
+ _webService.MapGetAndPost("/api/zones/dnssec/sign", _zonesApi.SignPrimaryZone);
+ _webService.MapGetAndPost("/api/zones/dnssec/unsign", _zonesApi.UnsignPrimaryZone);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/get", _zonesApi.GetPrimaryZoneDnssecProperties);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/convertToNSEC", _zonesApi.ConvertPrimaryZoneToNSEC);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/convertToNSEC3", _zonesApi.ConvertPrimaryZoneToNSEC3);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/updateNSEC3Params", _zonesApi.UpdatePrimaryZoneNSEC3Parameters);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/updateDnsKeyTtl", _zonesApi.UpdatePrimaryZoneDnssecDnsKeyTtl);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/generatePrivateKey", _zonesApi.GenerateAndAddPrimaryZoneDnssecPrivateKey);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/updatePrivateKey", _zonesApi.UpdatePrimaryZoneDnssecPrivateKey);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/deletePrivateKey", _zonesApi.DeletePrimaryZoneDnssecPrivateKey);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/publishAllPrivateKeys", _zonesApi.PublishAllGeneratedPrimaryZoneDnssecPrivateKeys);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/rolloverDnsKey", _zonesApi.RolloverPrimaryZoneDnsKey);
+ _webService.MapGetAndPost("/api/zones/dnssec/properties/retireDnsKey", _zonesApi.RetirePrimaryZoneDnsKey);
+ _webService.MapGetAndPost("/api/zones/records/add", _zonesApi.AddRecord);
+ _webService.MapGetAndPost("/api/zones/records/get", _zonesApi.GetRecords);
+ _webService.MapGetAndPost("/api/zones/records/update", _zonesApi.UpdateRecord);
+ _webService.MapGetAndPost("/api/zones/records/delete", _zonesApi.DeleteRecord);
//cache
- _webService.MapGet("/api/cache/list", _otherZonesApi.ListCachedZones);
- _webService.MapGet("/api/cache/delete", _otherZonesApi.DeleteCachedZone);
- _webService.MapGet("/api/cache/flush", _otherZonesApi.FlushCache);
+ _webService.MapGetAndPost("/api/cache/list", _otherZonesApi.ListCachedZones);
+ _webService.MapGetAndPost("/api/cache/delete", _otherZonesApi.DeleteCachedZone);
+ _webService.MapGetAndPost("/api/cache/flush", _otherZonesApi.FlushCache);
//allowed
- _webService.MapGet("/api/allowed/list", _otherZonesApi.ListAllowedZones);
- _webService.MapGet("/api/allowed/add", _otherZonesApi.AllowZone);
- _webService.MapGet("/api/allowed/delete", _otherZonesApi.DeleteAllowedZone);
- _webService.MapGet("/api/allowed/flush", _otherZonesApi.FlushAllowedZone);
- _webService.MapPost("/api/allowed/import", _otherZonesApi.ImportAllowedZones);
- _webService.MapGet("/api/allowed/export", _otherZonesApi.ExportAllowedZonesAsync);
+ _webService.MapGetAndPost("/api/allowed/list", _otherZonesApi.ListAllowedZones);
+ _webService.MapGetAndPost("/api/allowed/add", _otherZonesApi.AllowZone);
+ _webService.MapGetAndPost("/api/allowed/delete", _otherZonesApi.DeleteAllowedZone);
+ _webService.MapGetAndPost("/api/allowed/flush", _otherZonesApi.FlushAllowedZone);
+ _webService.MapGetAndPost("/api/allowed/import", _otherZonesApi.ImportAllowedZones);
+ _webService.MapGetAndPost("/api/allowed/export", _otherZonesApi.ExportAllowedZonesAsync);
//blocked
- _webService.MapGet("/api/blocked/list", _otherZonesApi.ListBlockedZones);
- _webService.MapGet("/api/blocked/add", _otherZonesApi.BlockZone);
- _webService.MapGet("/api/blocked/delete", _otherZonesApi.DeleteBlockedZone);
- _webService.MapGet("/api/blocked/flush", _otherZonesApi.FlushBlockedZone);
- _webService.MapPost("/api/blocked/import", _otherZonesApi.ImportBlockedZones);
- _webService.MapGet("/api/blocked/export", _otherZonesApi.ExportBlockedZonesAsync);
+ _webService.MapGetAndPost("/api/blocked/list", _otherZonesApi.ListBlockedZones);
+ _webService.MapGetAndPost("/api/blocked/add", _otherZonesApi.BlockZone);
+ _webService.MapGetAndPost("/api/blocked/delete", _otherZonesApi.DeleteBlockedZone);
+ _webService.MapGetAndPost("/api/blocked/flush", _otherZonesApi.FlushBlockedZone);
+ _webService.MapGetAndPost("/api/blocked/import", _otherZonesApi.ImportBlockedZones);
+ _webService.MapGetAndPost("/api/blocked/export", _otherZonesApi.ExportBlockedZonesAsync);
//apps
- _webService.MapGet("/api/apps/list", _appsApi.ListInstalledAppsAsync);
- _webService.MapGet("/api/apps/listStoreApps", _appsApi.ListStoreApps);
- _webService.MapGet("/api/apps/downloadAndInstall", _appsApi.DownloadAndInstallAppAsync);
- _webService.MapGet("/api/apps/downloadAndUpdate", _appsApi.DownloadAndUpdateAppAsync);
+ _webService.MapGetAndPost("/api/apps/list", _appsApi.ListInstalledAppsAsync);
+ _webService.MapGetAndPost("/api/apps/listStoreApps", _appsApi.ListStoreApps);
+ _webService.MapGetAndPost("/api/apps/downloadAndInstall", _appsApi.DownloadAndInstallAppAsync);
+ _webService.MapGetAndPost("/api/apps/downloadAndUpdate", _appsApi.DownloadAndUpdateAppAsync);
_webService.MapPost("/api/apps/install", _appsApi.InstallAppAsync);
_webService.MapPost("/api/apps/update", _appsApi.UpdateAppAsync);
- _webService.MapGet("/api/apps/uninstall", _appsApi.UninstallApp);
- _webService.MapGet("/api/apps/config/get", _appsApi.GetAppConfigAsync);
- _webService.MapPost("/api/apps/config/set", _appsApi.SetAppConfigAsync);
+ _webService.MapGetAndPost("/api/apps/uninstall", _appsApi.UninstallApp);
+ _webService.MapGetAndPost("/api/apps/config/get", _appsApi.GetAppConfigAsync);
+ _webService.MapGetAndPost("/api/apps/config/set", _appsApi.SetAppConfigAsync);
//dns client
- _webService.MapGet("/api/dnsClient/resolve", ResolveQueryAsync);
+ _webService.MapGetAndPost("/api/dnsClient/resolve", _api.ResolveQueryAsync);
//settings
- _webService.MapGet("/api/settings/get", _settingsApi.GetDnsSettings);
- _webService.MapGet("/api/settings/set", _settingsApi.SetDnsSettings);
- _webService.MapGet("/api/settings/getTsigKeyNames", _settingsApi.GetTsigKeyNames);
- _webService.MapGet("/api/settings/forceUpdateBlockLists", _settingsApi.ForceUpdateBlockLists);
- _webService.MapGet("/api/settings/temporaryDisableBlocking", _settingsApi.TemporaryDisableBlocking);
- _webService.MapGet("/api/settings/backup", _settingsApi.BackupSettingsAsync);
+ _webService.MapGetAndPost("/api/settings/get", _settingsApi.GetDnsSettings);
+ _webService.MapGetAndPost("/api/settings/set", _settingsApi.SetDnsSettings);
+ _webService.MapGetAndPost("/api/settings/getTsigKeyNames", _settingsApi.GetTsigKeyNames);
+ _webService.MapGetAndPost("/api/settings/forceUpdateBlockLists", _settingsApi.ForceUpdateBlockLists);
+ _webService.MapGetAndPost("/api/settings/temporaryDisableBlocking", _settingsApi.TemporaryDisableBlocking);
+ _webService.MapGetAndPost("/api/settings/backup", _settingsApi.BackupSettingsAsync);
_webService.MapPost("/api/settings/restore", _settingsApi.RestoreSettingsAsync);
//dhcp
- _webService.MapGet("/api/dhcp/leases/list", _dhcpApi.ListDhcpLeases);
- _webService.MapGet("/api/dhcp/leases/remove", _dhcpApi.RemoveDhcpLease);
- _webService.MapGet("/api/dhcp/leases/convertToReserved", _dhcpApi.ConvertToReservedLease);
- _webService.MapGet("/api/dhcp/leases/convertToDynamic", _dhcpApi.ConvertToDynamicLease);
- _webService.MapGet("/api/dhcp/scopes/list", _dhcpApi.ListDhcpScopes);
- _webService.MapGet("/api/dhcp/scopes/get", _dhcpApi.GetDhcpScope);
- _webService.MapGet("/api/dhcp/scopes/set", _dhcpApi.SetDhcpScopeAsync);
- _webService.MapGet("/api/dhcp/scopes/addReservedLease", _dhcpApi.AddReservedLease);
- _webService.MapGet("/api/dhcp/scopes/removeReservedLease", _dhcpApi.RemoveReservedLease);
- _webService.MapGet("/api/dhcp/scopes/enable", _dhcpApi.EnableDhcpScopeAsync);
- _webService.MapGet("/api/dhcp/scopes/disable", _dhcpApi.DisableDhcpScope);
- _webService.MapGet("/api/dhcp/scopes/delete", _dhcpApi.DeleteDhcpScope);
+ _webService.MapGetAndPost("/api/dhcp/leases/list", _dhcpApi.ListDhcpLeases);
+ _webService.MapGetAndPost("/api/dhcp/leases/remove", _dhcpApi.RemoveDhcpLease);
+ _webService.MapGetAndPost("/api/dhcp/leases/convertToReserved", _dhcpApi.ConvertToReservedLease);
+ _webService.MapGetAndPost("/api/dhcp/leases/convertToDynamic", _dhcpApi.ConvertToDynamicLease);
+ _webService.MapGetAndPost("/api/dhcp/scopes/list", _dhcpApi.ListDhcpScopes);
+ _webService.MapGetAndPost("/api/dhcp/scopes/get", _dhcpApi.GetDhcpScope);
+ _webService.MapGetAndPost("/api/dhcp/scopes/set", _dhcpApi.SetDhcpScopeAsync);
+ _webService.MapGetAndPost("/api/dhcp/scopes/addReservedLease", _dhcpApi.AddReservedLease);
+ _webService.MapGetAndPost("/api/dhcp/scopes/removeReservedLease", _dhcpApi.RemoveReservedLease);
+ _webService.MapGetAndPost("/api/dhcp/scopes/enable", _dhcpApi.EnableDhcpScopeAsync);
+ _webService.MapGetAndPost("/api/dhcp/scopes/disable", _dhcpApi.DisableDhcpScope);
+ _webService.MapGetAndPost("/api/dhcp/scopes/delete", _dhcpApi.DeleteDhcpScope);
//administration
- _webService.MapGet("/api/admin/sessions/list", _authApi.ListSessions);
- _webService.MapGet("/api/admin/sessions/createToken", _authApi.CreateApiToken);
- _webService.MapGet("/api/admin/sessions/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, true); });
- _webService.MapGet("/api/admin/users/list", _authApi.ListUsers);
- _webService.MapGet("/api/admin/users/create", _authApi.CreateUser);
- _webService.MapGet("/api/admin/users/get", _authApi.GetUserDetails);
- _webService.MapGet("/api/admin/users/set", _authApi.SetUserDetails);
- _webService.MapGet("/api/admin/users/delete", _authApi.DeleteUser);
- _webService.MapGet("/api/admin/groups/list", _authApi.ListGroups);
- _webService.MapGet("/api/admin/groups/create", _authApi.CreateGroup);
- _webService.MapGet("/api/admin/groups/get", _authApi.GetGroupDetails);
- _webService.MapGet("/api/admin/groups/set", _authApi.SetGroupDetails);
- _webService.MapGet("/api/admin/groups/delete", _authApi.DeleteGroup);
- _webService.MapGet("/api/admin/permissions/list", _authApi.ListPermissions);
- _webService.MapGet("/api/admin/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Unknown); });
- _webService.MapGet("/api/admin/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Unknown); });
+ _webService.MapGetAndPost("/api/admin/sessions/list", _authApi.ListSessions);
+ _webService.MapGetAndPost("/api/admin/sessions/createToken", _authApi.CreateApiToken);
+ _webService.MapGetAndPost("/api/admin/sessions/delete", delegate (HttpContext context) { _authApi.DeleteSession(context, true); });
+ _webService.MapGetAndPost("/api/admin/users/list", _authApi.ListUsers);
+ _webService.MapGetAndPost("/api/admin/users/create", _authApi.CreateUser);
+ _webService.MapGetAndPost("/api/admin/users/get", _authApi.GetUserDetails);
+ _webService.MapGetAndPost("/api/admin/users/set", _authApi.SetUserDetails);
+ _webService.MapGetAndPost("/api/admin/users/delete", _authApi.DeleteUser);
+ _webService.MapGetAndPost("/api/admin/groups/list", _authApi.ListGroups);
+ _webService.MapGetAndPost("/api/admin/groups/create", _authApi.CreateGroup);
+ _webService.MapGetAndPost("/api/admin/groups/get", _authApi.GetGroupDetails);
+ _webService.MapGetAndPost("/api/admin/groups/set", _authApi.SetGroupDetails);
+ _webService.MapGetAndPost("/api/admin/groups/delete", _authApi.DeleteGroup);
+ _webService.MapGetAndPost("/api/admin/permissions/list", _authApi.ListPermissions);
+ _webService.MapGetAndPost("/api/admin/permissions/get", delegate (HttpContext context) { _authApi.GetPermissionDetails(context, PermissionSection.Unknown); });
+ _webService.MapGetAndPost("/api/admin/permissions/set", delegate (HttpContext context) { _authApi.SetPermissionsDetails(context, PermissionSection.Unknown); });
//logs
- _webService.MapGet("/api/logs/list", _logsApi.ListLogs);
- _webService.MapGet("/api/logs/download", _logsApi.DownloadLogAsync);
- _webService.MapGet("/api/logs/delete", _logsApi.DeleteLog);
- _webService.MapGet("/api/logs/deleteAll", _logsApi.DeleteAllLogs);
- _webService.MapGet("/api/logs/query", _logsApi.QueryLogsAsync);
+ _webService.MapGetAndPost("/api/logs/list", _logsApi.ListLogs);
+ _webService.MapGetAndPost("/api/logs/download", _logsApi.DownloadLogAsync);
+ _webService.MapGetAndPost("/api/logs/delete", _logsApi.DeleteLog);
+ _webService.MapGetAndPost("/api/logs/deleteAll", _logsApi.DeleteAllLogs);
+ _webService.MapGetAndPost("/api/logs/query", _logsApi.QueryLogsAsync);
}
private async Task WebServiceApiMiddleware(HttpContext context, RequestDelegate next)
@@ -521,7 +592,7 @@ namespace DnsServerCore
private bool TryGetSession(HttpContext context, out UserSession session)
{
- string token = context.Request.GetQuery("token");
+ string token = context.Request.GetQueryOrForm("token");
session = _authManager.GetSession(token);
if ((session is null) || session.User.Disabled)
return false;
@@ -541,337 +612,11 @@ namespace DnsServerCore
#endregion
- #region update api
-
- private async Task CheckForUpdateAsync(HttpContext context)
- {
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
-
- if (_updateCheckUri is null)
- {
- jsonWriter.WriteBoolean("updateAvailable", false);
- return;
- }
-
- try
- {
- SocketsHttpHandler handler = new SocketsHttpHandler();
- handler.Proxy = _dnsServer.Proxy;
- handler.UseProxy = _dnsServer.Proxy is not null;
-
- using (HttpClient http = new HttpClient(handler))
- {
- Stream response = await http.GetStreamAsync(_updateCheckUri);
- using JsonDocument jsonDocument = await JsonDocument.ParseAsync(response);
- JsonElement jsonResponse = jsonDocument.RootElement;
-
- string updateVersion = jsonResponse.GetProperty("updateVersion").GetString();
- string updateTitle = jsonResponse.GetPropertyValue("updateTitle", null);
- string updateMessage = jsonResponse.GetPropertyValue("updateMessage", null);
- string downloadLink = jsonResponse.GetPropertyValue("downloadLink", null);
- string instructionsLink = jsonResponse.GetPropertyValue("instructionsLink", null);
- string changeLogLink = jsonResponse.GetPropertyValue("changeLogLink", null);
-
- bool updateAvailable = new Version(updateVersion) > _currentVersion;
-
- jsonWriter.WriteBoolean("updateAvailable", updateAvailable);
- jsonWriter.WriteString("updateVersion", updateVersion);
- jsonWriter.WriteString("currentVersion", GetCleanVersion(_currentVersion));
-
- if (updateAvailable)
- {
- jsonWriter.WriteString("updateTitle", updateTitle);
- jsonWriter.WriteString("updateMessage", updateMessage);
- jsonWriter.WriteString("downloadLink", downloadLink);
- jsonWriter.WriteString("instructionsLink", instructionsLink);
- jsonWriter.WriteString("changeLogLink", changeLogLink);
- }
-
- string strLog = "Check for update was done {updateAvailable: " + updateAvailable + "; updateVersion: " + updateVersion + ";";
-
- if (!string.IsNullOrEmpty(updateTitle))
- strLog += " updateTitle: " + updateTitle + ";";
-
- if (!string.IsNullOrEmpty(updateMessage))
- strLog += " updateMessage: " + updateMessage + ";";
-
- if (!string.IsNullOrEmpty(downloadLink))
- strLog += " downloadLink: " + downloadLink + ";";
-
- if (!string.IsNullOrEmpty(instructionsLink))
- strLog += " instructionsLink: " + instructionsLink + ";";
-
- if (!string.IsNullOrEmpty(changeLogLink))
- strLog += " changeLogLink: " + changeLogLink + ";";
-
- strLog += "}";
-
- _log.Write(context.GetRemoteEndPoint(), strLog);
- }
- }
- catch (Exception ex)
- {
- _log.Write(context.GetRemoteEndPoint(), "Check for update was done {updateAvailable: False;}\r\n" + ex.ToString());
-
- jsonWriter.WriteBoolean("updateAvailable", false);
- }
- }
-
- internal static string GetCleanVersion(Version version)
- {
- string strVersion = version.Major + "." + version.Minor;
-
- if (version.Build > 0)
- strVersion += "." + version.Build;
-
- if (version.Revision > 0)
- strVersion += "." + version.Revision;
-
- return strVersion;
- }
-
- internal string GetServerVersion()
- {
- return GetCleanVersion(_currentVersion);
- }
-
- #endregion
-
- #region dns client api
-
- private async Task ResolveQueryAsync(HttpContext context)
- {
- UserSession session = context.GetCurrentSession();
-
- if (!_authManager.IsPermitted(PermissionSection.DnsClient, session.User, PermissionFlag.View))
- throw new DnsWebServiceException("Access was denied.");
-
- HttpRequest request = context.Request;
-
- string server = request.GetQuery("server");
- string domain = request.GetQuery("domain").Trim(new char[] { '\t', ' ', '.' });
- DnsResourceRecordType type = request.GetQuery("type");
- DnsTransportProtocol protocol = request.GetQuery("protocol", DnsTransportProtocol.Udp);
- bool dnssecValidation = request.GetQuery("dnssec", bool.Parse, false);
- bool importResponse = request.GetQuery("import", bool.Parse, false);
- NetProxy proxy = _dnsServer.Proxy;
- bool preferIPv6 = _dnsServer.PreferIPv6;
- ushort udpPayloadSize = _dnsServer.UdpPayloadSize;
- bool randomizeName = false;
- bool qnameMinimization = _dnsServer.QnameMinimization;
- const int RETRIES = 1;
- const int TIMEOUT = 10000;
-
- DnsDatagram dnsResponse;
- string dnssecErrorMessage = null;
-
- if (server.Equals("recursive-resolver", StringComparison.OrdinalIgnoreCase))
- {
- if (type == DnsResourceRecordType.AXFR)
- throw new DnsServerException("Cannot do zone transfer (AXFR) for 'recursive-resolver'.");
-
- DnsQuestionRecord question;
-
- if ((type == DnsResourceRecordType.PTR) && IPAddress.TryParse(domain, out IPAddress address))
- question = new DnsQuestionRecord(address, DnsClass.IN);
- else
- question = new DnsQuestionRecord(domain, type, DnsClass.IN);
-
- DnsCache dnsCache = new DnsCache();
- dnsCache.MinimumRecordTtl = 0;
- dnsCache.MaximumRecordTtl = 7 * 24 * 60 * 60;
-
- try
- {
- dnsResponse = await DnsClient.RecursiveResolveAsync(question, dnsCache, proxy, preferIPv6, udpPayloadSize, randomizeName, qnameMinimization, false, dnssecValidation, null, RETRIES, TIMEOUT);
- }
- catch (DnsClientResponseDnssecValidationException ex)
- {
- dnsResponse = ex.Response;
- dnssecErrorMessage = ex.Message;
- importResponse = false;
- }
- }
- else
- {
- if ((type == DnsResourceRecordType.AXFR) && (protocol == DnsTransportProtocol.Udp))
- protocol = DnsTransportProtocol.Tcp;
-
- NameServerAddress nameServer;
-
- if (server.Equals("this-server", StringComparison.OrdinalIgnoreCase))
- {
- switch (protocol)
- {
- case DnsTransportProtocol.Udp:
- nameServer = _dnsServer.ThisServer;
- break;
-
- case DnsTransportProtocol.Tcp:
- nameServer = _dnsServer.ThisServer.ChangeProtocol(DnsTransportProtocol.Tcp);
- break;
-
- case DnsTransportProtocol.Tls:
- throw new DnsServerException("Cannot use DNS-over-TLS protocol for 'this-server'. Please use the TLS certificate domain name as the server.");
-
- case DnsTransportProtocol.Https:
- throw new DnsServerException("Cannot use DNS-over-HTTPS protocol for 'this-server'. Please use the TLS certificate domain name with a url as the server.");
-
- default:
- throw new NotSupportedException("DNS transport protocol is not supported: " + protocol.ToString());
- }
-
- proxy = null; //no proxy required for this server
- }
- else
- {
- nameServer = NameServerAddress.Parse(server);
-
- if (nameServer.Protocol != protocol)
- nameServer = nameServer.ChangeProtocol(protocol);
-
- if (nameServer.IsIPEndPointStale)
- {
- if (proxy is null)
- await nameServer.ResolveIPAddressAsync(_dnsServer, _dnsServer.PreferIPv6);
- }
- else if ((nameServer.DomainEndPoint is null) && ((protocol == DnsTransportProtocol.Udp) || (protocol == DnsTransportProtocol.Tcp)))
- {
- try
- {
- await nameServer.ResolveDomainNameAsync(_dnsServer);
- }
- catch
- { }
- }
- }
-
- DnsClient dnsClient = new DnsClient(nameServer);
-
- dnsClient.Proxy = proxy;
- dnsClient.PreferIPv6 = preferIPv6;
- dnsClient.RandomizeName = randomizeName;
- dnsClient.Retries = RETRIES;
- dnsClient.Timeout = TIMEOUT;
- dnsClient.UdpPayloadSize = udpPayloadSize;
- dnsClient.DnssecValidation = dnssecValidation;
-
- if (dnssecValidation)
- {
- //load trust anchors into dns client if domain is locally hosted
- _dnsServer.AuthZoneManager.LoadTrustAnchorsTo(dnsClient, domain, type);
- }
-
- try
- {
- dnsResponse = await dnsClient.ResolveAsync(domain, type);
- }
- catch (DnsClientResponseDnssecValidationException ex)
- {
- dnsResponse = ex.Response;
- dnssecErrorMessage = ex.Message;
- importResponse = false;
- }
-
- if (type == DnsResourceRecordType.AXFR)
- dnsResponse = dnsResponse.Join();
- }
-
- if (importResponse)
- {
- AuthZoneInfo zoneInfo = _dnsServer.AuthZoneManager.FindAuthZoneInfo(domain);
- if ((zoneInfo is null) || ((zoneInfo.Type == AuthZoneType.Secondary) && !zoneInfo.Name.Equals(domain, StringComparison.OrdinalIgnoreCase)))
- {
- if (!_authManager.IsPermitted(PermissionSection.Zones, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
-
- zoneInfo = _dnsServer.AuthZoneManager.CreatePrimaryZone(domain, _dnsServer.ServerDomain, false);
- if (zoneInfo is null)
- throw new DnsServerException("Cannot import records: failed to create primary zone.");
-
- //set permissions
- _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.ViewModifyDelete);
- _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _authManager.SetPermission(PermissionSection.Zones, zoneInfo.Name, _authManager.GetGroup(Group.DNS_ADMINISTRATORS), PermissionFlag.ViewModifyDelete);
- _authManager.SaveConfigFile();
- }
- else
- {
- if (!_authManager.IsPermitted(PermissionSection.Zones, zoneInfo.Name, session.User, PermissionFlag.Modify))
- throw new DnsWebServiceException("Access was denied.");
-
- switch (zoneInfo.Type)
- {
- case AuthZoneType.Primary:
- break;
-
- case AuthZoneType.Forwarder:
- if (type == DnsResourceRecordType.AXFR)
- throw new DnsServerException("Cannot import records via zone transfer: import zone must be of primary type.");
-
- break;
-
- default:
- throw new DnsServerException("Cannot import records: import zone must be of primary or forwarder type.");
- }
- }
-
- if (type == DnsResourceRecordType.AXFR)
- {
- _dnsServer.AuthZoneManager.SyncZoneTransferRecords(zoneInfo.Name, dnsResponse.Answer);
- }
- else
- {
- List importRecords = new List(dnsResponse.Answer.Count + dnsResponse.Authority.Count);
-
- foreach (DnsResourceRecord record in dnsResponse.Answer)
- {
- if (record.Name.Equals(zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || record.Name.EndsWith("." + zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || (zoneInfo.Name.Length == 0))
- {
- record.RemoveExpiry();
- importRecords.Add(record);
-
- if (record.Type == DnsResourceRecordType.NS)
- record.SyncGlueRecords(dnsResponse.Additional);
- }
- }
-
- foreach (DnsResourceRecord record in dnsResponse.Authority)
- {
- if (record.Name.Equals(zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || record.Name.EndsWith("." + zoneInfo.Name, StringComparison.OrdinalIgnoreCase) || (zoneInfo.Name.Length == 0))
- {
- record.RemoveExpiry();
- importRecords.Add(record);
-
- if (record.Type == DnsResourceRecordType.NS)
- record.SyncGlueRecords(dnsResponse.Additional);
- }
- }
-
- _dnsServer.AuthZoneManager.ImportRecords(zoneInfo.Name, importRecords);
- }
-
- _log.Write(context.GetRemoteEndPoint(), "[" + session.User.Username + "] DNS Client imported record(s) for authoritative zone {server: " + server + "; zone: " + zoneInfo.Name + "; type: " + type + ";}");
-
- _dnsServer.AuthZoneManager.SaveZoneFile(zoneInfo.Name);
- }
-
- Utf8JsonWriter jsonWriter = context.GetCurrentJsonWriter();
-
- if (dnssecErrorMessage is not null)
- jsonWriter.WriteString("warningMessage", dnssecErrorMessage);
-
- jsonWriter.WritePropertyName("result");
- dnsResponse.SerializeTo(jsonWriter);
- }
-
- #endregion
-
#region tls
internal void StartTlsCertificateUpdateTimer()
{
- if (_tlsCertificateUpdateTimer == null)
+ if (_tlsCertificateUpdateTimer is null)
{
_tlsCertificateUpdateTimer = new Timer(delegate (object state)
{
@@ -911,7 +656,7 @@ namespace DnsServerCore
internal void StopTlsCertificateUpdateTimer()
{
- if (_tlsCertificateUpdateTimer != null)
+ if (_tlsCertificateUpdateTimer is not null)
{
_tlsCertificateUpdateTimer.Dispose();
_tlsCertificateUpdateTimer = null;
@@ -928,9 +673,7 @@ namespace DnsServerCore
if (Path.GetExtension(tlsCertificatePath) != ".pfx")
throw new ArgumentException("Web Service TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
- X509Certificate2 certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
-
- _webServiceTlsCertificate = certificate;
+ _webServiceTlsCertificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
_webServiceTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
_log.Write("Web Service TLS certificate was loaded: " + tlsCertificatePath);
@@ -946,9 +689,7 @@ namespace DnsServerCore
if (Path.GetExtension(tlsCertificatePath) != ".pfx")
throw new ArgumentException("DNS Server TLS certificate file must be PKCS #12 formatted with .pfx extension: " + tlsCertificatePath);
- X509Certificate2 certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
-
- _dnsServer.Certificate = certificate;
+ _dnsServer.Certificate = new X509Certificate2(tlsCertificatePath, tlsCertificatePassword);
_dnsTlsCertificateLastModifiedOn = fileInfo.LastWriteTimeUtc;
_log.Write("DNS Server TLS certificate was loaded: " + tlsCertificatePath);
@@ -992,6 +733,22 @@ namespace DnsServerCore
#endregion
+ #region quic
+
+ internal static void ValidateQuicSupport()
+ {
+#pragma warning disable CA2252 // This API requires opting into preview features
+#pragma warning disable CA1416 // Validate platform compatibility
+
+ if (!QuicConnection.IsSupported)
+ throw new DnsWebServiceException("DNS-over-QUIC is supported only on Windows 11, Windows Server 2022, and Linux. On Linux, you must install 'libmsquic' and OpenSSL v1.1.1 manually.");
+
+#pragma warning restore CA1416 // Validate platform compatibility
+#pragma warning restore CA2252 // This API requires opting into preview features
+ }
+
+ #endregion
+
#region config
internal void LoadConfigFile()
@@ -1219,7 +976,7 @@ namespace DnsServerCore
int version = bR.ReadByte();
- if ((version >= 28) && (version <= 29))
+ if ((version >= 28) && (version <= 30))
{
ReadConfigFrom(bR, version);
}
@@ -1333,11 +1090,45 @@ namespace DnsServerCore
_dnsServer.TcpSendTimeout = bR.ReadInt32();
_dnsServer.TcpReceiveTimeout = bR.ReadInt32();
+ if (version >= 30)
+ {
+ _dnsServer.QuicIdleTimeout = bR.ReadInt32();
+ _dnsServer.QuicMaxInboundStreams = bR.ReadInt32();
+ _dnsServer.ListenBacklog = bR.ReadInt32();
+ }
+ else
+ {
+ _dnsServer.QuicIdleTimeout = 60000;
+ _dnsServer.QuicMaxInboundStreams = 100;
+ _dnsServer.ListenBacklog = 100;
+ }
+
//optional protocols
_dnsServer.EnableDnsOverHttp = bR.ReadBoolean();
_dnsServer.EnableDnsOverTls = bR.ReadBoolean();
_dnsServer.EnableDnsOverHttps = bR.ReadBoolean();
+ if (version >= 30)
+ {
+ _dnsServer.EnableDnsOverHttpPort80 = bR.ReadBoolean();
+ _dnsServer.EnableDnsOverQuic = bR.ReadBoolean();
+
+ _dnsServer.DnsOverHttpPort = bR.ReadInt32();
+ _dnsServer.DnsOverTlsPort = bR.ReadInt32();
+ _dnsServer.DnsOverHttpsPort = bR.ReadInt32();
+ _dnsServer.DnsOverQuicPort = bR.ReadInt32();
+ }
+ else
+ {
+ _dnsServer.EnableDnsOverHttpPort80 = _dnsServer.EnableDnsOverHttps;
+ _dnsServer.EnableDnsOverQuic = false;
+
+ _dnsServer.DnsOverHttpPort = 8053;
+ _dnsServer.DnsOverTlsPort = 853;
+ _dnsServer.DnsOverHttpsPort = 443;
+ _dnsServer.DnsOverQuicPort = 853;
+ }
+
_dnsTlsCertificatePath = bR.ReadShortString();
_dnsTlsCertificatePassword = bR.ReadShortString();
@@ -1413,6 +1204,11 @@ namespace DnsServerCore
_dnsServer.ResolverMaxStackCount = bR.ReadInt32();
//cache
+ if (version >= 30)
+ _saveCache = bR.ReadBoolean();
+ else
+ _saveCache = false;
+
_dnsServer.ServeStale = bR.ReadBoolean();
_dnsServer.CacheZoneManager.ServeStaleTtl = bR.ReadUInt32();
@@ -2102,7 +1898,7 @@ namespace DnsServerCore
private void WriteConfigTo(BinaryWriter bW)
{
bW.Write(Encoding.ASCII.GetBytes("DS")); //format
- bW.Write((byte)29); //version
+ bW.Write((byte)30); //version
//web service
{
@@ -2163,11 +1959,21 @@ namespace DnsServerCore
bW.Write(_dnsServer.ClientTimeout);
bW.Write(_dnsServer.TcpSendTimeout);
bW.Write(_dnsServer.TcpReceiveTimeout);
+ bW.Write(_dnsServer.QuicIdleTimeout);
+ bW.Write(_dnsServer.QuicMaxInboundStreams);
+ bW.Write(_dnsServer.ListenBacklog);
//optional protocols
bW.Write(_dnsServer.EnableDnsOverHttp);
bW.Write(_dnsServer.EnableDnsOverTls);
bW.Write(_dnsServer.EnableDnsOverHttps);
+ bW.Write(_dnsServer.EnableDnsOverHttpPort80);
+ bW.Write(_dnsServer.EnableDnsOverQuic);
+
+ bW.Write(_dnsServer.DnsOverHttpPort);
+ bW.Write(_dnsServer.DnsOverTlsPort);
+ bW.Write(_dnsServer.DnsOverHttpsPort);
+ bW.Write(_dnsServer.DnsOverQuicPort);
if (_dnsTlsCertificatePath == null)
bW.WriteShortString(string.Empty);
@@ -2230,6 +2036,7 @@ namespace DnsServerCore
bW.Write(_dnsServer.ResolverMaxStackCount);
//cache
+ bW.Write(_saveCache);
bW.Write(_dnsServer.ServeStale);
bW.Write(_dnsServer.CacheZoneManager.ServeStaleTtl);
@@ -2330,8 +2137,6 @@ namespace DnsServerCore
#endregion
- #endregion
-
#region public
public async Task StartAsync()
@@ -2402,12 +2207,28 @@ namespace DnsServerCore
});
}
- //start dns and dhcp
- _dnsServer.Start();
- _dhcpServer.Start();
+ //load dns cache async
+ if (_saveCache)
+ {
+ ThreadPool.QueueUserWorkItem(delegate (object state)
+ {
+ try
+ {
+ _dnsServer.CacheZoneManager.LoadCacheZoneFile();
+ }
+ catch (Exception ex)
+ {
+ _log.Write(ex);
+ }
+ });
+ }
//start web service
- await StartWebServiceAsync();
+ await TryStartWebServiceAsync();
+
+ //start dns and dhcp
+ await _dnsServer.StartAsync();
+ _dhcpServer.Start();
_log.Write("DNS Server (v" + _currentVersion.ToString() + ") was started successfully.");
}
@@ -2425,19 +2246,42 @@ namespace DnsServerCore
try
{
- await StopWebServiceAsync();
- _dnsServer.Dispose();
- _dhcpServer.Dispose();
+ //stop dns
+ if (_dnsServer is not null)
+ await _dnsServer.DisposeAsync();
+
+ //stop dhcp
+ if (_dhcpServer is not null)
+ _dhcpServer.Dispose();
+
+ //stop web service
+ if (_settingsApi is not null)
+ {
+ _settingsApi.StopBlockListUpdateTimer();
+ _settingsApi.StopTemporaryDisableBlockingTimer();
+ }
- _settingsApi.StopBlockListUpdateTimer();
- _settingsApi.StopTemporaryDisableBlockingTimer();
StopTlsCertificateUpdateTimer();
- _log.Write("DNS Server (v" + _currentVersion.ToString() + ") was stopped successfully.");
+ await StopWebServiceAsync();
+
+ if (_saveCache)
+ {
+ try
+ {
+ _dnsServer.CacheZoneManager.SaveCacheZoneFile();
+ }
+ catch (Exception ex)
+ {
+ _log.Write(ex);
+ }
+ }
+
+ _log?.Write("DNS Server (v" + _currentVersion.ToString() + ") was stopped successfully.");
}
catch (Exception ex)
{
- _log.Write("Failed to stop DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
+ _log?.Write("Failed to stop DNS Server (v" + _currentVersion.ToString() + ")\r\n" + ex.ToString());
throw;
}
}
@@ -2456,6 +2300,12 @@ namespace DnsServerCore
#region properties
+ internal DnsServer DnsServer
+ { get { return _dnsServer; } }
+
+ internal DhcpServer DhcpServer
+ { get { return _dhcpServer; } }
+
public string ConfigFolder
{ get { return _configFolder; } }