예제 #1
0
        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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #4
0
        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;
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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;
        }
예제 #9
0
        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);
        }
예제 #10
0
        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;
        }
예제 #11
0
        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);
        }