const int MAINTENANCE_TIMER_INTERVAL = 15 * 60 * 1000; //15 mins #endregion #region constructor private HealthService(IDnsServer dnsServer) { _dnsServer = dnsServer; _maintenanceTimer = new Timer(delegate(object state) { try { foreach (KeyValuePair <string, HealthMonitor> healthMonitor in _healthMonitors) { if (healthMonitor.Value.IsExpired()) { if (_healthMonitors.TryRemove(healthMonitor.Key, out HealthMonitor removedMonitor)) { removedMonitor.Dispose(); } } } } catch (Exception ex) { _dnsServer.WriteLog(ex); } finally { if (!_disposed) { _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite); } } }, null, Timeout.Infinite, Timeout.Infinite); _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite); }
const int MAINTENANCE_TIMER_INTERVAL = 15 * 60 * 1000; //15 mins #endregion #region constructor private HealthMonitoringService(IDnsServer dnsServer) { _dnsServer = dnsServer; _maintenanceTimer = new Timer(delegate(object state) { try { foreach (KeyValuePair <IPAddress, AddressMonitoring> monitoring in _addressMonitoring) { if (monitoring.Value.IsExpired()) { if (_addressMonitoring.TryRemove(monitoring.Key, out AddressMonitoring removedMonitoring)) { removedMonitoring.Dispose(); } } } foreach (KeyValuePair <string, DomainMonitoring> monitoring in _domainMonitoringA) { if (monitoring.Value.IsExpired()) { if (_domainMonitoringA.TryRemove(monitoring.Key, out DomainMonitoring removedMonitoring)) { removedMonitoring.Dispose(); } } } foreach (KeyValuePair <string, DomainMonitoring> monitoring in _domainMonitoringAAAA) { if (monitoring.Value.IsExpired()) { if (_domainMonitoringAAAA.TryRemove(monitoring.Key, out DomainMonitoring removedMonitoring)) { removedMonitoring.Dispose(); } } } } catch (Exception ex) { _dnsServer.WriteLog(ex); } finally { if (!_disposed) { _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite); } } }, null, Timeout.Infinite, Timeout.Infinite); _maintenanceTimer.Change(MAINTENANCE_TIMER_INTERVAL, Timeout.Infinite); }
internal async Task InitializeAsync() { string config = await GetConfigAsync(); foreach (KeyValuePair <string, IDnsApplication> app in _dnsApplications) { try { await app.Value.InitializeAsync(_dnsServer, config); } catch (Exception ex) { _dnsServer.WriteLog(ex); } } }
private void StartWebServer() { if (_state != ServiceState.Stopped) { throw new InvalidOperationException("Web server is already running."); } _state = ServiceState.Starting; //bind to local addresses foreach (IPAddress localAddress in _webServerLocalAddresses) { //bind to HTTP port 80 { IPEndPoint httpEP = new IPEndPoint(localAddress, 80); Socket httpListener = null; try { httpListener = new Socket(httpEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); httpListener.Bind(httpEP); httpListener.Listen(100); _httpListeners.Add(httpListener); _dnsServer.WriteLog("Web server was bound successfully: " + httpEP.ToString()); } catch (Exception ex) { _dnsServer.WriteLog(ex); if (httpListener is not null) { httpListener.Dispose(); } } } //bind to HTTPS port 443 if (_webServerTlsCertificate is not null) { IPEndPoint httpsEP = new IPEndPoint(localAddress, 443); Socket httpsListener = null; try { httpsListener = new Socket(httpsEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp); httpsListener.Bind(httpsEP); httpsListener.Listen(100); _httpsListeners.Add(httpsListener); _dnsServer.WriteLog("Web server was bound successfully: " + httpsEP.ToString()); } catch (Exception ex) { _dnsServer.WriteLog(ex); if (httpsListener is not null) { httpsListener.Dispose(); } } } } //start reading requests int listenerTaskCount = Math.Max(1, Environment.ProcessorCount); foreach (Socket httpListener in _httpListeners) { for (int i = 0; i < listenerTaskCount; i++) { _ = Task.Factory.StartNew(delegate() { return(AcceptConnectionAsync(httpListener, false)); }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Current); } } foreach (Socket httpsListener in _httpsListeners) { for (int i = 0; i < listenerTaskCount; i++) { _ = Task.Factory.StartNew(delegate() { return(AcceptConnectionAsync(httpsListener, true)); }, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Current); } } _state = ServiceState.Running; }
public async Task InitializeAsync(IDnsServer dnsServer, string config) { _dnsServer = dnsServer; dynamic jsonConfig = JsonConvert.DeserializeObject(config); { List <IPAddress> webServerLocalAddresses = new List <IPAddress>(); foreach (dynamic jsonAddress in jsonConfig.webServerLocalAddresses) { webServerLocalAddresses.Add(IPAddress.Parse(jsonAddress.Value)); } _webServerLocalAddresses = webServerLocalAddresses; } if (jsonConfig.webServerUseSelfSignedTlsCertificate is null) { _webServerUseSelfSignedTlsCertificate = true; } else { _webServerUseSelfSignedTlsCertificate = jsonConfig.webServerUseSelfSignedTlsCertificate.Value; } _webServerTlsCertificateFilePath = jsonConfig.webServerTlsCertificateFilePath.Value; _webServerTlsCertificatePassword = jsonConfig.webServerTlsCertificatePassword.Value; _webServerRootPath = jsonConfig.webServerRootPath.Value; if (!Path.IsPathRooted(_webServerRootPath)) { _webServerRootPath = Path.Combine(_dnsServer.ApplicationFolder, _webServerRootPath); } _serveBlockPageFromWebServerRoot = jsonConfig.serveBlockPageFromWebServerRoot.Value; string blockPageTitle = jsonConfig.blockPageTitle.Value; string blockPageHeading = jsonConfig.blockPageHeading.Value; string blockPageMessage = jsonConfig.blockPageMessage.Value; string blockPageContent = @"<html> <head> <title>" + (blockPageTitle is null ? "" : blockPageTitle) + @"</title> </head> <body> " + (blockPageHeading is null ? "" : " <h1>" + blockPageHeading + "</h1>") + @" " + (blockPageMessage is null ? "" : " <p>" + blockPageMessage + "</p>") + @" </body> </html>"; _blockPageContent = Encoding.UTF8.GetBytes(blockPageContent); try { StopWebServer(); string selfSignedCertificateFilePath = Path.Combine(_dnsServer.ApplicationFolder, "cert.pfx"); if (_webServerUseSelfSignedTlsCertificate) { if (!File.Exists(selfSignedCertificateFilePath)) { RSA rsa = RSA.Create(2048); CertificateRequest req = new CertificateRequest("cn=" + _dnsServer.ServerDomain, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); X509Certificate2 cert = req.CreateSelfSigned(DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(5)); await File.WriteAllBytesAsync(selfSignedCertificateFilePath, cert.Export(X509ContentType.Pkcs12, null as string)); } } else { File.Delete(selfSignedCertificateFilePath); } if (string.IsNullOrEmpty(_webServerTlsCertificateFilePath)) { StopTlsCertificateUpdateTimer(); if (_webServerUseSelfSignedTlsCertificate) { LoadWebServiceTlsCertificate(selfSignedCertificateFilePath, null); } else { //disable HTTPS _webServerTlsCertificate = null; } } else { LoadWebServiceTlsCertificate(_webServerTlsCertificateFilePath, _webServerTlsCertificatePassword); StartTlsCertificateUpdateTimer(); } StartWebServer(); } catch (Exception ex) { _dnsServer.WriteLog(ex); } if (jsonConfig.webServerUseSelfSignedTlsCertificate is null) { config = config.Replace("\"webServerTlsCertificateFilePath\"", "\"webServerUseSelfSignedTlsCertificate\": true,\r\n \"webServerTlsCertificateFilePath\""); await File.WriteAllTextAsync(Path.Combine(dnsServer.ApplicationFolder, "dnsApp.config"), config); } }
public HealthMonitor(IDnsServer dnsServer, IPAddress address, HealthCheck healthCheck, Uri healthCheckUrl) { _dnsServer = dnsServer; _address = address; _healthCheck = healthCheck; _healthCheckTimer = new Timer(async delegate(object state) { try { if (_healthCheck is null) { _lastHealthCheckResponse = null; } else { HealthCheckResponse healthCheckResponse = await _healthCheck.IsHealthyAsync(_address, healthCheckUrl); bool statusChanged = false; bool maintenance = false; if (_lastHealthCheckResponse is null) { switch (healthCheckResponse.Status) { case HealthStatus.Failed: statusChanged = true; break; case HealthStatus.Maintenance: statusChanged = true; maintenance = true; break; } } else { if (_lastHealthCheckResponse.Status != healthCheckResponse.Status) { statusChanged = true; if ((_lastHealthCheckResponse.Status == HealthStatus.Maintenance) || (healthCheckResponse.Status == HealthStatus.Maintenance)) { maintenance = true; } } } if (statusChanged) { switch (healthCheckResponse.Status) { case HealthStatus.Failed: _dnsServer.WriteLog("ALERT! Address [" + _address.ToString() + "] status is FAILED based on '" + _healthCheck.Name + "' health check. The failure reason is: " + healthCheckResponse.FailureReason); break; default: _dnsServer.WriteLog("ALERT! Address [" + _address.ToString() + "] status is " + healthCheckResponse.Status.ToString().ToUpper() + " based on '" + _healthCheck.Name + "' health check."); break; } if (healthCheckResponse.Exception is not null) { _dnsServer.WriteLog(healthCheckResponse.Exception); } if (!maintenance) { //avoid sending email alerts when switching from or to maintenance EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, healthCheckResponse); } } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, healthCheckResponse); } } _lastHealthCheckResponse = healthCheckResponse; } } catch (Exception ex) { _dnsServer.WriteLog(ex); if (_lastHealthCheckResponse is null) { EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, ex); } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, ex); } _lastHealthCheckResponse = new HealthCheckResponse(HealthStatus.Failed, ex.ToString(), ex); } else { _lastHealthCheckResponse = null; } } finally { if (!_disposed && (_healthCheck is not null)) { _healthCheckTimer.Change(_healthCheck.Interval, Timeout.Infinite); } } }, null, Timeout.Infinite, Timeout.Infinite); _healthCheckTimer.Change(HEALTH_CHECK_TIMER_INITIAL_INTERVAL, Timeout.Infinite); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { _dnsServer = dnsServer; dynamic jsonConfig = JsonConvert.DeserializeObject(config); _enableLogging = jsonConfig.enableLogging.Value; _maxLogDays = Convert.ToInt32(jsonConfig.maxLogDays.Value); string sqliteDbPath = jsonConfig.sqliteDbPath.Value; string connectionString = jsonConfig.connectionString.Value; if (!Path.IsPathRooted(sqliteDbPath)) { sqliteDbPath = Path.Combine(_dnsServer.ApplicationFolder, sqliteDbPath); } _connectionString = connectionString.Replace("{sqliteDbPath}", sqliteDbPath); using (SqliteConnection connection = new SqliteConnection(_connectionString)) { connection.Open(); using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = @" CREATE TABLE IF NOT EXISTS dns_logs ( dlid INTEGER PRIMARY KEY, timestamp DATETIME NOT NULL, client_ip VARCHAR(39) NOT NULL, protocol TINYINT NOT NULL, response_type TINYINT NOT NULL, rcode TINYINT NOT NULL, qname VARCHAR(255), qtype SMALLINT, qclass SMALLINT, answer TEXT ); "; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp ON dns_logs (timestamp);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_client_ip ON dns_logs (client_ip);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_protocol ON dns_logs (protocol);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_response_type ON dns_logs (response_type);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_rcode ON dns_logs (rcode);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_qname ON dns_logs (qname);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_qtype ON dns_logs (qtype);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_qclass ON dns_logs (qclass);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp_client_ip ON dns_logs (timestamp, client_ip);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_timestamp_qname ON dns_logs (timestamp, qname);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_client_qname ON dns_logs (client_ip, qname);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_query ON dns_logs (qname, qtype);"; command.ExecuteNonQuery(); } using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "CREATE INDEX IF NOT EXISTS index_all ON dns_logs (timestamp, client_ip, protocol, response_type, rcode, qname, qtype, qclass);"; command.ExecuteNonQuery(); } } if (_enableLogging) { _queueTimer = new Timer(delegate(object state) { try { BulkInsertLogs(); } catch (Exception ex) { _dnsServer.WriteLog(ex); } finally { if (_queueTimer is not null) { _queueTimer.Change(QUEUE_TIMER_INTERVAL, Timeout.Infinite); } } }); _queueTimer.Change(QUEUE_TIMER_INTERVAL, Timeout.Infinite); } else { if (_queueTimer is not null) { _queueTimer.Dispose(); _queueTimer = null; } } if (_maxLogDays < 1) { if (_cleanupTimer is not null) { _cleanupTimer.Dispose(); _cleanupTimer = null; } } else { _cleanupTimer = new Timer(delegate(object state) { try { using (SqliteConnection connection = new SqliteConnection(_connectionString)) { connection.Open(); using (SqliteCommand command = connection.CreateCommand()) { command.CommandText = "DELETE FROM dns_logs WHERE timestamp < @timestamp;"; command.Parameters.AddWithValue("@timestamp", DateTime.UtcNow.AddDays(_maxLogDays * -1)); command.ExecuteNonQuery(); } } } catch (Exception ex) { _dnsServer.WriteLog(ex); } finally { if (_cleanupTimer is not null) { _cleanupTimer.Change(CLEAN_UP_TIMER_PERIODIC_INTERVAL, Timeout.Infinite); } } }); _cleanupTimer.Change(CLEAN_UP_TIMER_INITIAL_INTERVAL, Timeout.Infinite); } return(Task.CompletedTask); }
public DnsApplication(IDnsServer dnsServer, string appName) { _dnsServer = dnsServer; _appName = appName; //load DLLs and handlers Dictionary <string, IDnsApplicationRequestHandler> dnsRequestHandlers = new Dictionary <string, IDnsApplicationRequestHandler>(); Type dnsAppInterface = typeof(IDnsApplicationRequestHandler); Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (string dllFile in Directory.GetFiles(_dnsServer.ApplicationFolder, "*.dll", SearchOption.TopDirectoryOnly)) { string dllFileName = Path.GetFileNameWithoutExtension(dllFile); bool isLoaded = false; foreach (Assembly loadedAssembly in loadedAssemblies) { AssemblyName assemblyName = loadedAssembly.GetName(); if (assemblyName.CodeBase != null) { if (Path.GetFileNameWithoutExtension(assemblyName.CodeBase).Equals(dllFileName, StringComparison.OrdinalIgnoreCase)) { isLoaded = true; break; } } else if ((assemblyName.Name != null) && assemblyName.Name.Equals(dllFileName, StringComparison.OrdinalIgnoreCase)) { isLoaded = true; break; } } if (isLoaded) { continue; } Assembly assembly; try { string pdbFile = Path.Combine(_dnsServer.ApplicationFolder, Path.GetFileNameWithoutExtension(dllFile) + ".pdb"); if (File.Exists(pdbFile)) { using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read)) { using (FileStream pdbStream = new FileStream(pdbFile, FileMode.Open, FileAccess.Read)) { assembly = _appContext.LoadFromStream(dllStream, pdbStream); } } } else { using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read)) { assembly = _appContext.LoadFromStream(dllStream); } } } catch (Exception ex) { _dnsServer.WriteLog(ex); continue; } foreach (Type classType in assembly.ExportedTypes) { foreach (Type interfaceType in classType.GetInterfaces()) { if (interfaceType == dnsAppInterface) { IDnsApplicationRequestHandler handler = Activator.CreateInstance(classType) as IDnsApplicationRequestHandler; dnsRequestHandlers.TryAdd(classType.FullName, handler); } } } } _dnsRequestHandlers = dnsRequestHandlers; }
public Task InitializeAsync(IDnsServer dnsServer, string config) { _dnsServer = dnsServer; dynamic jsonConfig = JsonConvert.DeserializeObject(config); { List <IPAddress> webServerLocalAddresses = new List <IPAddress>(); foreach (dynamic jsonAddress in jsonConfig.webServerLocalAddresses) { webServerLocalAddresses.Add(IPAddress.Parse(jsonAddress.Value)); } _webServerLocalAddresses = webServerLocalAddresses; } _webServerTlsCertificateFilePath = jsonConfig.webServerTlsCertificateFilePath?.Value; _webServerTlsCertificatePassword = jsonConfig.webServerTlsCertificatePassword?.Value; _webServerRootPath = jsonConfig.webServerRootPath?.Value; if (!Path.IsPathRooted(_webServerRootPath)) { _webServerRootPath = Path.Combine(_dnsServer.ApplicationFolder, _webServerRootPath); } _serveBlockPageFromWebServerRoot = jsonConfig.serveBlockPageFromWebServerRoot?.Value; string blockPageTitle = jsonConfig.blockPageTitle?.Value; string blockPageHeading = jsonConfig.blockPageHeading?.Value; string blockPageMessage = jsonConfig.blockPageMessage?.Value; string blockPageContent = @"<html> <head> <title>" + (blockPageTitle is null ? "" : blockPageTitle) + @"</title> </head> <body> " + (blockPageHeading is null ? "" : " <h1>" + blockPageHeading + "</h1>") + @" " + (blockPageMessage is null ? "" : " <p>" + blockPageMessage + "</p>") + @" </body> </html>"; _blockPageContent = Encoding.UTF8.GetBytes(blockPageContent); try { StopWebServer(); if (string.IsNullOrEmpty(_webServerTlsCertificateFilePath)) { StopTlsCertificateUpdateTimer(); _webServerTlsCertificate = null; } else { LoadWebServiceTlsCertificate(); StartTlsCertificateUpdateTimer(); } StartWebServer(); } catch (Exception ex) { _dnsServer.WriteLog(ex); } return(Task.CompletedTask); }
public DnsApplication(IDnsServer dnsServer, string name) { _dnsServer = dnsServer; _name = name; _appContext = new DnsApplicationAssemblyLoadContext(_dnsServer.ApplicationFolder); //load app assemblies Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies(); List <Assembly> appAssemblies = new List <Assembly>(); foreach (string dllFile in Directory.GetFiles(_dnsServer.ApplicationFolder, "*.dll", SearchOption.TopDirectoryOnly)) { string dllFileName = Path.GetFileNameWithoutExtension(dllFile); bool isLoaded = false; foreach (Assembly loadedAssembly in loadedAssemblies) { AssemblyName assemblyName = loadedAssembly.GetName(); if (assemblyName.CodeBase != null) { if (Path.GetFileNameWithoutExtension(assemblyName.CodeBase).Equals(dllFileName, StringComparison.OrdinalIgnoreCase)) { isLoaded = true; break; } } else if ((assemblyName.Name != null) && assemblyName.Name.Equals(dllFileName, StringComparison.OrdinalIgnoreCase)) { isLoaded = true; break; } } if (isLoaded) { continue; } try { string pdbFile = Path.Combine(_dnsServer.ApplicationFolder, Path.GetFileNameWithoutExtension(dllFile) + ".pdb"); if (File.Exists(pdbFile)) { using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read)) { using (FileStream pdbStream = new FileStream(pdbFile, FileMode.Open, FileAccess.Read)) { appAssemblies.Add(_appContext.LoadFromStream(dllStream, pdbStream)); } } } else { using (FileStream dllStream = new FileStream(dllFile, FileMode.Open, FileAccess.Read)) { appAssemblies.Add(_appContext.LoadFromStream(dllStream)); } } } catch (Exception ex) { _dnsServer.WriteLog(ex); } } //load apps Dictionary <string, IDnsApplication> dnsApplications = new Dictionary <string, IDnsApplication>(); Dictionary <string, IDnsAppRecordRequestHandler> dnsAppRecordRequestHandlers = new Dictionary <string, IDnsAppRecordRequestHandler>(2); Dictionary <string, IDnsRequestController> dnsRequestControllers = new Dictionary <string, IDnsRequestController>(1); Dictionary <string, IDnsAuthoritativeRequestHandler> dnsAuthoritativeRequestHandlers = new Dictionary <string, IDnsAuthoritativeRequestHandler>(1); Dictionary <string, IDnsQueryLogger> dnsQueryLoggers = new Dictionary <string, IDnsQueryLogger>(1); Type dnsApplicationInterface = typeof(IDnsApplication); foreach (Assembly appAssembly in appAssemblies) { try { foreach (Type classType in appAssembly.ExportedTypes) { bool isDnsApp = false; foreach (Type interfaceType in classType.GetInterfaces()) { if (interfaceType == dnsApplicationInterface) { isDnsApp = true; break; } } if (isDnsApp) { try { IDnsApplication app = Activator.CreateInstance(classType) as IDnsApplication; dnsApplications.Add(classType.FullName, app); if (app is IDnsAppRecordRequestHandler appRecordHandler) { dnsAppRecordRequestHandlers.Add(classType.FullName, appRecordHandler); } if (app is IDnsRequestController requestController) { dnsRequestControllers.Add(classType.FullName, requestController); } if (app is IDnsAuthoritativeRequestHandler requestHandler) { dnsAuthoritativeRequestHandlers.Add(classType.FullName, requestHandler); } if (app is IDnsQueryLogger logger) { dnsQueryLoggers.Add(classType.FullName, logger); } if (_version is null) { _version = appAssembly.GetName().Version; } } catch (Exception ex) { _dnsServer.WriteLog(ex); } } } } catch (Exception ex) { _dnsServer.WriteLog(ex); } } if (_version is null) { if (dnsApplications.Count > 0) { _version = new Version(1, 0); } else { _version = new Version(0, 0); } } _dnsApplications = dnsApplications; _dnsAppRecordRequestHandlers = dnsAppRecordRequestHandlers; _dnsRequestControllers = dnsRequestControllers; _dnsAuthoritativeRequestHandlers = dnsAuthoritativeRequestHandlers; _dnsQueryLoggers = dnsQueryLoggers; }
public HealthMonitor(IDnsServer dnsServer, IPAddress address, HealthCheck healthCheck) { _dnsServer = dnsServer; _address = address; _healthCheck = healthCheck; _healthCheckTimer = new Timer(async delegate(object state) { try { if (_healthCheck is null) { _healthCheckStatus = null; } else { HealthCheckStatus healthCheckStatus = await _healthCheck.IsHealthyAsync(_address); bool sendAlert = false; if (_healthCheckStatus is null) { if (!healthCheckStatus.IsHealthy) { sendAlert = true; } } else { if (_healthCheckStatus.IsHealthy != healthCheckStatus.IsHealthy) { sendAlert = true; } else if (_healthCheckStatus.FailureReason != healthCheckStatus.FailureReason) { sendAlert = true; } } if (sendAlert) { EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, healthCheckStatus); } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, healthCheckStatus); } } _healthCheckStatus = healthCheckStatus; } } catch (Exception ex) { _dnsServer.WriteLog(ex); if (_healthCheckStatus is null) { EmailAlert emailAlert = _healthCheck.EmailAlert; if (emailAlert is not null) { _ = emailAlert.SendAlertAsync(_address, _healthCheck.Name, ex); } WebHook webHook = _healthCheck.WebHook; if (webHook is not null) { _ = webHook.CallAsync(_address, _healthCheck.Name, ex); } _healthCheckStatus = new HealthCheckStatus(false, ex.ToString()); } else { _healthCheckStatus = null; } } finally { if (!_disposed && (_healthCheck is not null)) { _healthCheckTimer.Change(_healthCheck.Interval, Timeout.Infinite); } } }, null, Timeout.Infinite, Timeout.Infinite); _healthCheckTimer.Change(0, Timeout.Infinite); }