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); }
public static MaxMind Create(IDnsServer dnsServer) { if (_maxMind is null) { _maxMind = new MaxMind(dnsServer); } return(_maxMind); }
public static HealthService Create(IDnsServer dnsServer) { if (_healthService is null) { _healthService = new HealthService(dnsServer); } return(_healthService); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { dynamic jsonConfig = JsonConvert.DeserializeObject(config); _enableBlocking = jsonConfig.enableBlocking.Value; if (jsonConfig.allowedNetworks is null) { _allowedNetworks = Array.Empty <NetworkAddress>(); } else { List <NetworkAddress> allowedNetworks = new List <NetworkAddress>(); foreach (dynamic allowedNetwork in jsonConfig.allowedNetworks) { allowedNetworks.Add(NetworkAddress.Parse(allowedNetwork.Value)); } _allowedNetworks = allowedNetworks; } if (jsonConfig.blockedNetworks is null) { _blockedNetworks = Array.Empty <NetworkAddress>(); } else { List <NetworkAddress> blockedNetworks = new List <NetworkAddress>(); foreach (dynamic blockedNetwork in jsonConfig.blockedNetworks) { blockedNetworks.Add(NetworkAddress.Parse(blockedNetwork.Value)); } _blockedNetworks = blockedNetworks; } if (jsonConfig.blockedQuestions is null) { _blockedQuestions = Array.Empty <BlockedQuestion>(); } else { List <BlockedQuestion> blockedQuestions = new List <BlockedQuestion>(); foreach (dynamic blockedQuestion in jsonConfig.blockedQuestions) { blockedQuestions.Add(new BlockedQuestion(blockedQuestion)); } _blockedQuestions = blockedQuestions; } return(Task.CompletedTask); }
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); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { if (_healthService is null) { _healthService = HealthService.Create(dnsServer); } _healthService.Initialize(JsonConvert.DeserializeObject(config)); return(Task.CompletedTask); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { if (_healthMonitor is null) { _healthMonitor = HealthMonitoringService.Create(dnsServer); } //let Address class initialize config return(Task.CompletedTask); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { _soaRecord = new DnsSOARecord(dnsServer.ServerDomain, "hostadmin." + dnsServer.ServerDomain, 1, 14400, 3600, 604800, 60); dynamic jsonConfig = JsonConvert.DeserializeObject(config); _enableBlocking = jsonConfig.enableBlocking.Value; _allowTxtBlockingReport = jsonConfig.allowTxtBlockingReport.Value; _blockListZone = ReadJsonDomainArray(jsonConfig.blocked); return(Task.CompletedTask); }
private MaxMind(IDnsServer dnsServer) { string mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoIP2-Country.mmdb"); if (!File.Exists(mmFile)) { mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoLite2-Country.mmdb"); } if (!File.Exists(mmFile)) { throw new FileNotFoundException("MaxMind Country file is missing!"); } _mmCountryReader = new DatabaseReader(mmFile); }
/// <summary> /// Initializes a new instance of the <see cref="WhitelistManager"/> class. /// </summary> /// <param name="dateTimeProvider">The provider for datetime.</param> /// <param name="loggerFactory">The factory to create the logger.</param> /// <param name="peerAddressManager">The manager implementation for peer addresses.</param> /// <param name="dnsServer">The DNS server.</param> /// <param name="connectionSettings">The connection settings.</param> public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, ConnectionManagerSettings connectionSettings, DnsSettings dnsSettings) { Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider)); Guard.NotNull(loggerFactory, nameof(loggerFactory)); Guard.NotNull(peerAddressManager, nameof(peerAddressManager)); Guard.NotNull(dnsServer, nameof(dnsServer)); Guard.NotNull(dnsSettings, nameof(dnsSettings)); Guard.NotNull(connectionSettings, nameof(connectionSettings)); this.dateTimeProvider = dateTimeProvider; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.peerAddressManager = peerAddressManager; this.dnsServer = dnsServer; this.dnsSettings = dnsSettings; this.externalEndpoint = connectionSettings.ExternalEndpoint; }
/// <summary> /// Initializes a new instance of the <see cref="DnsFeature"/> class. /// </summary> /// <param name="dnsServer">The DNS server.</param> /// <param name="whitelistManager">The whitelist manager.</param> /// <param name="loggerFactory">The factory to create the logger.</param> /// <param name="nodeLifetime">The node lifetime object used for graceful shutdown.</param> /// <param name="nodeSettings">The node settings object containing node configuration.</param> /// <param name="dataFolders">The data folders of the system.</param> /// <param name="asyncLoopFactory">The asynchronous loop factory.</param> public DnsFeature(IDnsServer dnsServer, IWhitelistManager whitelistManager, ILoggerFactory loggerFactory, INodeLifetime nodeLifetime, NodeSettings nodeSettings, DataFolder dataFolders, IAsyncLoopFactory asyncLoopFactory) { Guard.NotNull(dnsServer, nameof(dnsServer)); Guard.NotNull(whitelistManager, nameof(whitelistManager)); Guard.NotNull(loggerFactory, nameof(loggerFactory)); Guard.NotNull(nodeLifetime, nameof(nodeLifetime)); Guard.NotNull(nodeSettings, nameof(nodeSettings)); Guard.NotNull(dataFolders, nameof(dataFolders)); Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory)); this.dnsServer = dnsServer; this.whitelistManager = whitelistManager; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.asyncLoopFactory = asyncLoopFactory; this.nodeLifetime = nodeLifetime; this.nodeSettings = nodeSettings; this.dataFolders = dataFolders; }
/// <summary> /// Initializes a new instance of the <see cref="WhitelistManager"/> class. /// </summary> /// <param name="dateTimeProvider">The provider for datetime.</param> /// <param name="loggerFactory">The factory to create the logger.</param> /// <param name="peerAddressManager">The manager implementation for peer addresses.</param> /// <param name="dnsServer">The DNS server.</param> /// <param name="connectionSettings">The connection settings.</param> /// <param name="dnsSettings">The DNS settings.</param> /// <param name="peerBanning">Peer banning component.</param> public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, ConnectionManagerSettings connectionSettings, DnsSettings dnsSettings, IPeerBanning peerBanning) { Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider)); Guard.NotNull(loggerFactory, nameof(loggerFactory)); Guard.NotNull(peerAddressManager, nameof(peerAddressManager)); Guard.NotNull(dnsServer, nameof(dnsServer)); Guard.NotNull(dnsSettings, nameof(dnsSettings)); Guard.NotNull(connectionSettings, nameof(connectionSettings)); Guard.NotNull(peerBanning, nameof(peerBanning)); this.dateTimeProvider = dateTimeProvider; this.logger = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode"); this.peerAddressManager = peerAddressManager; this.dnsServer = dnsServer; this.dnsSettings = dnsSettings; this.externalEndpoint = connectionSettings.ExternalEndpoint; this.peerBanning = peerBanning; }
/// <summary> /// Initializes a new instance of the <see cref="WhitelistManager"/> class. /// </summary> /// <param name="dateTimeProvider">The provider for datetime.</param> /// <param name="loggerFactory">The factory to create the logger.</param> /// <param name="peerAddressManager">The manager implementation for peer addresses.</param> /// <param name="dnsServer">The DNS server.</param> /// <param name="nodeSettings">The node settings.</param> public WhitelistManager(IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, IPeerAddressManager peerAddressManager, IDnsServer dnsServer, NodeSettings nodeSettings) { Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider)); Guard.NotNull(loggerFactory, nameof(loggerFactory)); Guard.NotNull(peerAddressManager, nameof(peerAddressManager)); Guard.NotNull(dnsServer, nameof(dnsServer)); Guard.NotNull(nodeSettings, nameof(nodeSettings)); Guard.NotNull(nodeSettings.DnsHostName, nameof(nodeSettings.DnsHostName)); Guard.NotNull(nodeSettings.ConnectionManager, nameof(nodeSettings.ConnectionManager)); this.dateTimeProvider = dateTimeProvider; this.logger = loggerFactory.CreateLogger(this.GetType().FullName); this.peerAddressManager = peerAddressManager; this.dnsServer = dnsServer; this.dnsPeerBlacklistThresholdInSeconds = nodeSettings.DnsPeerBlacklistThresholdInSeconds; this.dnsHostName = nodeSettings.DnsHostName; this.externalEndpoint = nodeSettings.ConnectionManager.ExternalEndpoint; this.fullNodeMode = nodeSettings.DnsFullNode; }
public Task InitializeAsync(IDnsServer dnsServer, string config) { if (_mmCountryReader == null) { string mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoIP2-Country.mmdb"); if (!File.Exists(mmFile)) { mmFile = Path.Combine(dnsServer.ApplicationFolder, "GeoLite2-Country.mmdb"); } if (!File.Exists(mmFile)) { throw new FileNotFoundException("MaxMind Country file is missing!"); } _mmCountryReader = new DatabaseReader(mmFile); } return(Task.CompletedTask); }
/// <summary> /// Initializes a new instance of the <see cref="DnsFeature"/> class. /// </summary> /// <param name="dnsServer">The DNS server.</param> /// <param name="whitelistManager">The whitelist manager.</param> /// <param name="loggerFactory">The factory to create the logger.</param> /// <param name="nodeLifetime">The node lifetime object used for graceful shutdown.</param> /// <param name="nodeSettings">The node settings object containing node configuration.</param> /// <param name="dnsSettings">Defines the DNS settings for the node</param> /// <param name="dataFolders">The data folders of the system.</param> /// <param name="asyncLoopFactory">The asynchronous loop factory.</param> /// <param name="connectionManager">Manager of node's network connections.</param> /// <param name="unreliablePeerBehavior">Instance of the UnreliablePeerBehavior that will be added to the connectionManager Template.</param> public DnsFeature(IDnsServer dnsServer, IWhitelistManager whitelistManager, ILoggerFactory loggerFactory, INodeLifetime nodeLifetime, DnsSettings dnsSettings, NodeSettings nodeSettings, DataFolder dataFolders, IAsyncLoopFactory asyncLoopFactory, IConnectionManager connectionManager, UnreliablePeerBehavior unreliablePeerBehavior) { Guard.NotNull(dnsServer, nameof(dnsServer)); Guard.NotNull(whitelistManager, nameof(whitelistManager)); Guard.NotNull(loggerFactory, nameof(loggerFactory)); Guard.NotNull(nodeLifetime, nameof(nodeLifetime)); Guard.NotNull(nodeSettings, nameof(nodeSettings)); Guard.NotNull(dataFolders, nameof(dataFolders)); Guard.NotNull(asyncLoopFactory, nameof(asyncLoopFactory)); Guard.NotNull(connectionManager, nameof(connectionManager)); Guard.NotNull(unreliablePeerBehavior, nameof(unreliablePeerBehavior)); this.dnsServer = dnsServer; this.whitelistManager = whitelistManager; this.logger = loggerFactory.CreateLogger("Impleum.Bitcoin.FullNode"); this.asyncLoopFactory = asyncLoopFactory; this.nodeLifetime = nodeLifetime; this.nodeSettings = nodeSettings; this.dnsSettings = dnsSettings; this.dataFolders = dataFolders; this.connectionManager = connectionManager; this.unreliablePeerBehavior = unreliablePeerBehavior; }
public async Task InitializeAsync(IDnsServer dnsServer, string config) { dynamic jsonConfig = JsonConvert.DeserializeObject(config); _enableBlocking = jsonConfig.enableBlocking.Value; if (jsonConfig.dropMalformedRequests is null) { _dropMalformedRequests = false; } else { _dropMalformedRequests = jsonConfig.dropMalformedRequests.Value; } if (jsonConfig.allowedNetworks is null) { _allowedNetworks = Array.Empty <NetworkAddress>(); } else { List <NetworkAddress> allowedNetworks = new List <NetworkAddress>(); foreach (dynamic allowedNetwork in jsonConfig.allowedNetworks) { allowedNetworks.Add(NetworkAddress.Parse(allowedNetwork.Value)); } _allowedNetworks = allowedNetworks; } if (jsonConfig.blockedNetworks is null) { _blockedNetworks = Array.Empty <NetworkAddress>(); } else { List <NetworkAddress> blockedNetworks = new List <NetworkAddress>(); foreach (dynamic blockedNetwork in jsonConfig.blockedNetworks) { blockedNetworks.Add(NetworkAddress.Parse(blockedNetwork.Value)); } _blockedNetworks = blockedNetworks; } if (jsonConfig.blockedQuestions is null) { _blockedQuestions = Array.Empty <BlockedQuestion>(); } else { List <BlockedQuestion> blockedQuestions = new List <BlockedQuestion>(); foreach (dynamic blockedQuestion in jsonConfig.blockedQuestions) { blockedQuestions.Add(new BlockedQuestion(blockedQuestion)); } _blockedQuestions = blockedQuestions; } if (jsonConfig.dropMalformedRequests is null) { config = config.Replace("\"allowedNetworks\"", "\"dropMalformedRequests\": false,\r\n \"allowedNetworks\""); await File.WriteAllTextAsync(Path.Combine(dnsServer.ApplicationFolder, "dnsApp.config"), config); } }
public DnsClientInternal(IDnsServer dnsServer) { _dnsServer = dnsServer; }
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); _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 Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { DnsQuestionRecord question = request.Question[0]; dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); string healthCheck = jsonAppRecordData.healthCheck?.Value; IReadOnlyList <DnsResourceRecord> answers; if (question.Type == DnsResourceRecordType.TXT) { bool allowTxtStatus; if (jsonAppRecordData.allowTxtStatus == null) { allowTxtStatus = false; } else { allowTxtStatus = jsonAppRecordData.allowTxtStatus.Value; } if (!allowTxtStatus) { return(Task.FromResult <DnsDatagram>(null)); } List <DnsResourceRecord> txtAnswers = new List <DnsResourceRecord>(); GetStatusAnswers(jsonAppRecordData.primary.Value, true, question, 30, healthCheck, txtAnswers); foreach (dynamic jsonDomain in jsonAppRecordData.secondary) { GetStatusAnswers(jsonDomain.Value, false, question, 30, healthCheck, txtAnswers); } answers = txtAnswers; } else { answers = GetAnswers(jsonAppRecordData.primary.Value, question, zoneName, appRecordTtl, healthCheck); if (answers is null) { foreach (dynamic jsonDomain in jsonAppRecordData.secondary) { answers = GetAnswers(jsonDomain.Value, question, zoneName, appRecordTtl, healthCheck); if (answers is not null) { break; } } if (answers is null) { return(Task.FromResult <DnsDatagram>(null)); } } } return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers))); }
public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); dynamic jsonCname; if (NetUtilities.IsPrivateIP(remoteEP.Address)) { jsonCname = jsonAppRecordData.@private; } else { jsonCname = jsonAppRecordData.@public; } if (jsonCname == null) { return(Task.FromResult <DnsDatagram>(null)); } string cname = jsonCname.Value; if (string.IsNullOrEmpty(cname)) { return(Task.FromResult <DnsDatagram>(null)); } IReadOnlyList <DnsResourceRecord> answers; if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex { answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) } } ; //use ANAME else { answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) } }; return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers))); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { //do nothing return(Task.CompletedTask); }
public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { DnsResourceRecord answer; switch (request.Question[0].Type) { case DnsResourceRecordType.A: if (remoteEP.AddressFamily == AddressFamily.InterNetwork) { answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(remoteEP.Address)); } else { return(Task.FromResult <DnsDatagram>(null)); } break; case DnsResourceRecordType.AAAA: if (remoteEP.AddressFamily == AddressFamily.InterNetworkV6) { answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(remoteEP.Address)); } else { return(Task.FromResult <DnsDatagram>(null)); } break; case DnsResourceRecordType.TXT: answer = new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.TXT, DnsClass.IN, appRecordTtl, new DnsTXTRecord(remoteEP.Address.ToString())); break; default: return(Task.FromResult <DnsDatagram>(null)); } return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, new DnsResourceRecord[] { answer }))); }
public Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { switch (request.Question[0].Type) { case DnsResourceRecordType.A: case DnsResourceRecordType.AAAA: Location location = null; if (_mmCityReader.TryCity(remoteEP.Address, out CityResponse response)) { location = response.Location; } dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); dynamic jsonClosestServer = null; if ((location == null) || !location.HasCoordinates) { jsonClosestServer = jsonAppRecordData[0]; } else { double lastDistance = double.MaxValue; foreach (dynamic jsonServer in jsonAppRecordData) { double lat = Convert.ToDouble(jsonServer.lat.Value); double @long = Convert.ToDouble([email protected]); double distance = GetDistance(lat, @long, location.Latitude.Value, location.Longitude.Value); if (distance < lastDistance) { lastDistance = distance; jsonClosestServer = jsonServer; } } } if (jsonClosestServer == null) { return(Task.FromResult <DnsDatagram>(null)); } List <DnsResourceRecord> answers = new List <DnsResourceRecord>(); foreach (dynamic jsonAddress in jsonClosestServer.addresses) { IPAddress address = IPAddress.Parse(jsonAddress.Value); switch (request.Question[0].Type) { case DnsResourceRecordType.A: if (address.AddressFamily == AddressFamily.InterNetwork) { answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(address))); } break; case DnsResourceRecordType.AAAA: if (address.AddressFamily == AddressFamily.InterNetworkV6) { answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(address))); } break; } } if (answers.Count == 0) { return(Task.FromResult <DnsDatagram>(null)); } return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers))); default: return(Task.FromResult <DnsDatagram>(null)); } }
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 Task <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { switch (request.Question[0].Type) { case DnsResourceRecordType.A: case DnsResourceRecordType.AAAA: dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); dynamic jsonAddresses; if (NetUtilities.IsPrivateIP(remoteEP.Address)) { jsonAddresses = jsonAppRecordData.@private; } else { jsonAddresses = jsonAppRecordData.@public; } if (jsonAddresses == null) { return(Task.FromResult <DnsDatagram>(null)); } List <DnsResourceRecord> answers = new List <DnsResourceRecord>(); foreach (dynamic jsonAddress in jsonAddresses) { IPAddress address = IPAddress.Parse(jsonAddress.Value); switch (request.Question[0].Type) { case DnsResourceRecordType.A: if (address.AddressFamily == AddressFamily.InterNetwork) { answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.A, DnsClass.IN, appRecordTtl, new DnsARecord(address))); } break; case DnsResourceRecordType.AAAA: if (address.AddressFamily == AddressFamily.InterNetworkV6) { answers.Add(new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.AAAA, DnsClass.IN, appRecordTtl, new DnsAAAARecord(address))); } break; } } if (answers.Count == 0) { return(Task.FromResult <DnsDatagram>(null)); } return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers))); default: return(Task.FromResult <DnsDatagram>(null)); } }
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 <DnsDatagram> ProcessRequestAsync(DnsDatagram request, IPEndPoint remoteEP, string zoneName, uint appRecordTtl, string appRecordData, bool isRecursionAllowed, IDnsServer dnsServer) { string continent; if (_mmCountryReader.TryCountry(remoteEP.Address, out CountryResponse response)) { continent = response.Continent.Code; } else { continent = "default"; } dynamic jsonAppRecordData = JsonConvert.DeserializeObject(appRecordData); dynamic jsonCname = jsonAppRecordData[continent]; if (jsonCname != null) { string cname = jsonCname.Value; if (!string.IsNullOrEmpty(cname)) { IReadOnlyList <DnsResourceRecord> answers; if (request.Question[0].Name.Equals(zoneName, StringComparison.OrdinalIgnoreCase)) //check for zone apex { answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.ANAME, DnsClass.IN, appRecordTtl, new DnsANAMERecord(cname)) } } ; //use ANAME else { answers = new DnsResourceRecord[] { new DnsResourceRecord(request.Question[0].Name, DnsResourceRecordType.CNAME, DnsClass.IN, appRecordTtl, new DnsCNAMERecord(cname)) } }; return(Task.FromResult(new DnsDatagram(request.Identifier, true, request.OPCODE, true, false, request.RecursionDesired, isRecursionAllowed, false, false, DnsResponseCode.NoError, request.Question, answers))); } } return(Task.FromResult <DnsDatagram>(null)); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { _maxMind = MaxMind.Create(dnsServer); return(Task.CompletedTask); }
public Task InitializeAsync(IDnsServer dnsServer, string config) { //no config needed return(Task.CompletedTask); }