public PrimaryZone(DnsServer dnsServer, string name, string primaryNameServer, bool @internal) : base(name) { _dnsServer = dnsServer; _internal = @internal; if (_internal) { _zoneTransfer = AuthZoneTransfer.Deny; _notify = AuthZoneNotify.None; } else { _zoneTransfer = AuthZoneTransfer.AllowOnlyZoneNameServers; _notify = AuthZoneNotify.ZoneNameServers; _notifyTimer = new Timer(NotifyTimerCallback, null, Timeout.Infinite, Timeout.Infinite); _notifyList = new List <NameServerAddress>(); } DnsSOARecord soa = new DnsSOARecord(primaryNameServer, _name.Length == 0 ? "hostadmin" : "hostadmin." + _name, 1, 14400, 3600, 604800, 900); _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; _entries[DnsResourceRecordType.NS] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.NS, DnsClass.IN, soa.Refresh, new DnsNSRecord(soa.PrimaryNameServer)) }; }
public async Task <IReadOnlyList <NameServerAddress> > GetSecondaryNameServerAddressesAsync(DnsServer dnsServer) { List <NameServerAddress> nameServers = new List <NameServerAddress>(); DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; IReadOnlyList <DnsResourceRecord> nsRecords = GetRecords(DnsResourceRecordType.NS); //stub zone has no authority so cant use QueryRecords foreach (DnsResourceRecord nsRecord in nsRecords) { if (nsRecord.IsDisabled()) { continue; } string nsDomain = (nsRecord.RDATA as DnsNSRecord).NameServer; if (soa.PrimaryNameServer.Equals(nsDomain, StringComparison.OrdinalIgnoreCase)) { continue; //skip primary name server } nameServers.AddRange(await GetNameServerAddressesAsync(dnsServer, nsRecord)); } return(nameServers); }
private void UpdateServerDomain(string serverDomain) { _soaRecord = new DnsSOARecord(serverDomain, "hostadmin." + serverDomain, 1, 14400, 3600, 604800, 900); _nsRecord = new DnsNSRecord(serverDomain); _zoneManager.ServerDomain = serverDomain; }
public IReadOnlyList <NameServerAddress> GetPrimaryNameServerAddresses(DnsServer dnsServer) { List <NameServerAddress> nameServers = new List <NameServerAddress>(); DnsResourceRecord soaRecord = _entries[DnsResourceRecordType.SOA][0]; DnsSOARecord soa = soaRecord.RDATA as DnsSOARecord; IReadOnlyList <DnsResourceRecord> nsRecords = GetRecords(DnsResourceRecordType.NS); //stub zone has no authority so cant use QueryRecords foreach (DnsResourceRecord nsRecord in nsRecords) { if (nsRecord.IsDisabled()) { continue; } string nsDomain = (nsRecord.RDATA as DnsNSRecord).NameServer; if (soa.PrimaryNameServer.Equals(nsDomain, StringComparison.OrdinalIgnoreCase)) { //found primary NS nameServers.AddRange(GetNameServerAddresses(dnsServer, nsRecord)); break; } } foreach (NameServerAddress nameServer in GetNameServerAddresses(dnsServer, soaRecord)) { if (!nameServers.Contains(nameServer)) { nameServers.Add(nameServer); } } return(nameServers); }
/// <inheritdoc/> public MockDnsZone(MockDnsServer server, string domainName) : base(server, domainName) { if (server == null) { throw new ArgumentNullException(nameof(server)); } var records = new List <DnsRecord>(); // add mock SOA record var soaRecord = new DnsSOARecord( zone: this, name: domainName, @class: DnsRecordClasses.IN, timeToLive: TimeSpan.FromHours(1), primaryServer: server.DomainName, responsiblePerson: "hostmaster.", serial: 1, refreshInterval: TimeSpan.FromMinutes(15), retryDelay: TimeSpan.FromMinutes(10), expireLimit: TimeSpan.FromDays(1), minimumTimeToLive: TimeSpan.FromHours(1)); records.Add(soaRecord); // add mock NS record var nsRecord = new DnsNSRecord(this, domainName, DnsRecordClasses.IN, TimeSpan.FromHours(1), server.DomainName); records.Add(nsRecord); this.records = records; }
internal PrimaryZone(DnsServer dnsServer, string name, DnsSOARecord soa, DnsNSRecord ns) : base(name) { _dnsServer = dnsServer; _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; _entries[DnsResourceRecordType.NS] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.NS, DnsClass.IN, soa.Refresh, ns) }; _notifyTimer = new Timer(NotifyTimerCallback, null, Timeout.Infinite, Timeout.Infinite); }
internal AuthZoneInfo CreateInternalPrimaryZone(string domain, DnsSOARecord soaRecord, DnsNSRecord ns) { AuthZone authZone = new PrimaryZone(_dnsServer, domain, soaRecord, ns); if (_root.TryAdd(authZone)) { return(new AuthZoneInfo(authZone)); } return(null); }
internal PrimaryZone(DnsServer dnsServer, string name, DnsSOARecord soa, DnsNSRecord ns) : base(name) { _dnsServer = dnsServer; _internal = true; _zoneTransfer = AuthZoneTransfer.Deny; _notify = AuthZoneNotify.None; _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; _entries[DnsResourceRecordType.NS] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.NS, DnsClass.IN, soa.Refresh, ns) }; }
public PrimaryZone(DnsServer dnsServer, string name, string primaryNameServer, bool @internal) : base(name) { _dnsServer = dnsServer; _internal = @internal; DnsSOARecord soa = new DnsSOARecord(primaryNameServer, "hostadmin." + name, 1, 14400, 3600, 604800, 900); _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; _entries[DnsResourceRecordType.NS] = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.NS, DnsClass.IN, soa.Refresh, new DnsNSRecord(soa.PrimaryNameServer)) }; _notifyTimer = new Timer(NotifyTimerCallback, null, Timeout.Infinite, Timeout.Infinite); }
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); }
public static async Task <StubZone> CreateAsync(DnsServer dnsServer, string name, string primaryNameServerAddresses = null) { StubZone stubZone = new StubZone(name); stubZone._dnsServer = dnsServer; DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN); DnsDatagram soaResponse = null; if (primaryNameServerAddresses == null) { soaResponse = await stubZone._dnsServer.DirectQueryAsync(soaQuestion); } else { DnsClient dnsClient = new DnsClient(primaryNameServerAddresses); dnsClient.Proxy = stubZone._dnsServer.Proxy; dnsClient.PreferIPv6 = stubZone._dnsServer.PreferIPv6; soaResponse = await dnsClient.ResolveAsync(soaQuestion); } if ((soaResponse == null) || (soaResponse.Answer.Count == 0) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA)) { throw new DnsServerException("DNS Server failed to find SOA record for: " + name); } DnsSOARecord receivedSoa = soaResponse.Answer[0].RDATA as DnsSOARecord; DnsSOARecord soa = new DnsSOARecord(receivedSoa.PrimaryNameServer, receivedSoa.ResponsiblePerson, receivedSoa.Serial - 1, receivedSoa.Refresh, receivedSoa.Retry, receivedSoa.Expire, receivedSoa.Minimum); DnsResourceRecord[] soaRR = new DnsResourceRecord[] { new DnsResourceRecord(stubZone._name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; if (!string.IsNullOrEmpty(primaryNameServerAddresses)) { soaRR[0].SetGlueRecords(primaryNameServerAddresses); } stubZone._entries[DnsResourceRecordType.SOA] = soaRR; stubZone._isExpired = true; //new stub zone is considered expired till it refreshes stubZone._refreshTimer = new Timer(stubZone.RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite); return(stubZone); }
public SecondaryZone(DnsServer dnsServer, string name, string primaryNameServerAddresses = null) : base(name) { _dnsServer = dnsServer; DnsQuestionRecord soaQuestion = new DnsQuestionRecord(name, DnsResourceRecordType.SOA, DnsClass.IN); DnsDatagram soaResponse = null; if (primaryNameServerAddresses == null) { soaResponse = _dnsServer.DirectQuery(soaQuestion); } else { DnsClient dnsClient = new DnsClient(primaryNameServerAddresses); dnsClient.Proxy = _dnsServer.Proxy; dnsClient.PreferIPv6 = _dnsServer.PreferIPv6; dnsClient.Retries = _dnsServer.Retries; dnsClient.Timeout = _dnsServer.Timeout; soaResponse = dnsClient.Resolve(soaQuestion); } if ((soaResponse == null) || (soaResponse.Answer.Count == 0) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA)) { throw new DnsServerException("DNS Server failed to find SOA record for: " + name); } DnsSOARecord receivedSoa = soaResponse.Answer[0].RDATA as DnsSOARecord; DnsSOARecord soa = new DnsSOARecord(receivedSoa.PrimaryNameServer, receivedSoa.ResponsiblePerson, receivedSoa.Serial - 1, receivedSoa.Refresh, receivedSoa.Retry, receivedSoa.Expire, receivedSoa.Minimum); DnsResourceRecord[] soaRR = new DnsResourceRecord[] { new DnsResourceRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN, soa.Refresh, soa) }; if (!string.IsNullOrEmpty(primaryNameServerAddresses)) { soaRR[0].SetGlueRecords(primaryNameServerAddresses); } _entries[DnsResourceRecordType.SOA] = soaRR; _isExpired = true; //new secondary zone is considered expired till it refreshes _refreshTimer = new Timer(RefreshTimerCallback, null, Timeout.Infinite, Timeout.Infinite); }
protected void CleanupHistory(List <DnsResourceRecord> history) { DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; DateTime expiry = DateTime.UtcNow.AddSeconds(-soa.Expire); int index = 0; while (index < history.Count) { //check difference sequence if (history[index].GetDeletedOn() > expiry) { break; //found record to keep } //skip to next difference sequence index++; int soaCount = 1; while (index < history.Count) { if (history[index].Type == DnsResourceRecordType.SOA) { soaCount++; if (soaCount == 3) { break; } } index++; } } if (index == history.Count) { //delete entire history history.Clear(); return; } //remove expired records history.RemoveRange(0, index); }
public void IncrementSoaSerial() { DnsResourceRecord record = _entries[DnsResourceRecordType.SOA][0]; DnsSOARecord soa = record.RDATA as DnsSOARecord; uint serial = soa.Serial; if (serial < uint.MaxValue) { serial++; } else { serial = 0; } DnsResourceRecord newRecord = new DnsResourceRecord(record.Name, record.Type, record.Class, record.TtlValue, new DnsSOARecord(soa.PrimaryNameServer, soa.ResponsiblePerson, serial, soa.Refresh, soa.Retry, soa.Expire, soa.Minimum)) { Tag = record.Tag }; _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { newRecord }; }
private async Task <bool> RefreshZoneAsync(IReadOnlyList <NameServerAddress> primaryNameServers) { try { { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server has started zone refresh for stub zone: " + _name); } } DnsClient client = new DnsClient(primaryNameServers); client.Timeout = REFRESH_TIMEOUT; client.Retries = REFRESH_RETRIES; DnsDatagram soaRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN) }); DnsDatagram soaResponse = await client.ResolveAsync(soaRequest); if (soaResponse.RCODE != DnsResponseCode.NoError) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received RCODE=" + soaResponse.RCODE.ToString() + " for '" + _name + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(false); } if (soaResponse.Answer.Count < 1) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received an empty response for SOA query for '" + _name + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(false); } DnsSOARecord currentSoaRecord = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; DnsSOARecord receivedSoaRecord = soaResponse.Answer[0].RDATA as DnsSOARecord; //compare using sequence space arithmetic if (!currentSoaRecord.IsZoneUpdateAvailable(receivedSoaRecord)) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server successfully checked for update to '" + _name + "' stub zone from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(true); } //update available; do zone sync with TCP transport List <NameServerAddress> tcpNameServers = new List <NameServerAddress>(); foreach (NameServerAddress nameServer in primaryNameServers) { tcpNameServers.Add(new NameServerAddress(nameServer, DnsTransportProtocol.Tcp)); } primaryNameServers = tcpNameServers; client = new DnsClient(primaryNameServers); client.Timeout = REFRESH_TIMEOUT; client.Retries = REFRESH_RETRIES; DnsDatagram nsRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.NS, DnsClass.IN) }); DnsDatagram nsResponse = await client.ResolveAsync(nsRequest); if (nsResponse.RCODE != DnsResponseCode.NoError) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received RCODE=" + nsResponse.RCODE.ToString() + " for '" + _name + "' stub zone refresh from: " + nsResponse.Metadata.NameServerAddress.ToString()); } return(false); } if (nsResponse.Answer.Count < 1) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received an empty response for NS query for '" + _name + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString()); } return(false); } List <DnsResourceRecord> allRecords = new List <DnsResourceRecord>(); allRecords.AddRange(nsResponse.Answer); allRecords.AddRange(soaResponse.Answer); //to sync latest SOA record _dnsServer.AuthZoneManager.SyncRecords(_name, allRecords, nsResponse.Additional, true); { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server successfully refreshed '" + _name + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString()); } } return(true); } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { string strNameServers = null; foreach (NameServerAddress nameServer in primaryNameServers) { if (strNameServers == null) { strNameServers = nameServer.ToString(); } else { strNameServers += ", " + nameServer.ToString(); } } log.Write("DNS Server failed to refresh '" + _name + "' stub zone from: " + strNameServers); log.Write(ex); } return(false); } }
private async void RefreshTimerCallback(object state) { if (_disabled) { return; } try { _isExpired = DateTime.UtcNow > _expiry; //get primary name server addresses IReadOnlyList <NameServerAddress> primaryNameServers = await GetPrimaryNameServerAddressesAsync(_dnsServer); if (primaryNameServers.Count == 0) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server could not find primary name server IP addresses for stub zone: " + _name); } //set timer for retry DnsSOARecord soa1 = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; _refreshTimer.Change(soa1.Retry * 1000, Timeout.Infinite); return; } //refresh zone if (await RefreshZoneAsync(primaryNameServers)) { //zone refreshed; set timer for refresh DnsSOARecord latestSoa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; _refreshTimer.Change(latestSoa.Refresh * 1000, Timeout.Infinite); _expiry = DateTime.UtcNow.AddSeconds(latestSoa.Expire); _isExpired = false; _dnsServer.AuthZoneManager.SaveZoneFile(_name); return; } //no response from any of the name servers; set timer for retry DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; _refreshTimer.Change(soa.Retry * 1000, Timeout.Infinite); } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write(ex); } //set timer for retry lock (_refreshTimerLock) { if (_refreshTimer != null) { DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; _refreshTimer.Change(soa.Retry * 1000, Timeout.Infinite); } } } }
private void UpdateServerDomain(string serverDomain) { ThreadPool.QueueUserWorkItem(delegate(object state) { //update authoritative zone SOA and NS records try { List <AuthZoneInfo> zones = ListZones(); foreach (AuthZoneInfo zone in zones) { if (zone.Type != AuthZoneType.Primary) { continue; } DnsResourceRecord record = zone.GetRecords(DnsResourceRecordType.SOA)[0]; DnsSOARecord soa = record.RDATA as DnsSOARecord; if (soa.PrimaryNameServer.Equals(_serverDomain, StringComparison.OrdinalIgnoreCase)) { string responsiblePerson = soa.ResponsiblePerson; if (responsiblePerson.EndsWith(_serverDomain)) { responsiblePerson = responsiblePerson.Replace(_serverDomain, serverDomain); } SetRecords(record.Name, record.Type, record.TtlValue, new DnsResourceRecordData[] { new DnsSOARecord(serverDomain, responsiblePerson, soa.Serial, soa.Refresh, soa.Retry, soa.Expire, soa.Minimum) }); //update NS records IReadOnlyList <DnsResourceRecord> nsResourceRecords = zone.GetRecords(DnsResourceRecordType.NS); foreach (DnsResourceRecord nsResourceRecord in nsResourceRecords) { if ((nsResourceRecord.RDATA as DnsNSRecord).NameServer.Equals(_serverDomain, StringComparison.OrdinalIgnoreCase)) { UpdateRecord(nsResourceRecord, new DnsResourceRecord(nsResourceRecord.Name, nsResourceRecord.Type, nsResourceRecord.Class, nsResourceRecord.TtlValue, new DnsNSRecord(serverDomain)) { Tag = nsResourceRecord.Tag }); break; } } if (zone.Internal) { continue; //dont save internal zones to disk } try { SaveZoneFile(zone.Name); } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write(ex); } } } } } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write(ex); } } //update server domain _serverDomain = serverDomain; }); }
private async void RefreshTimerCallback(object state) { try { if (_disabled && !_resync) { return; } _isExpired = DateTime.UtcNow > _expiry; //get all name server addresses IReadOnlyList <NameServerAddress> nameServers = await GetAllNameServerAddressesAsync(_dnsServer); if (nameServers.Count == 0) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server could not find name server IP addresses for stub zone: " + (_name == "" ? "<root>" : _name)); } //set timer for retry DnsSOARecord soa1 = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; ResetRefreshTimer(soa1.Retry * 1000); return; } //refresh zone if (await RefreshZoneAsync(nameServers)) { //zone refreshed; set timer for refresh DnsSOARecord latestSoa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; ResetRefreshTimer(latestSoa.Refresh * 1000); _expiry = DateTime.UtcNow.AddSeconds(latestSoa.Expire); _isExpired = false; _resync = false; _dnsServer.AuthZoneManager.SaveZoneFile(_name); return; } //no response from any of the name servers; set timer for retry DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; ResetRefreshTimer(soa.Retry * 1000); } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write(ex); } //set timer for retry DnsSOARecord soa = _entries[DnsResourceRecordType.SOA][0].RDATA as DnsSOARecord; ResetRefreshTimer(soa.Retry * 1000); } finally { _refreshTimerTriggered = false; } }
private async Task <bool> RefreshZoneAsync(IReadOnlyList <NameServerAddress> nameServers) { try { { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server has started zone refresh for stub zone: " + (_name == "" ? "<root>" : _name)); } } DnsClient client = new DnsClient(nameServers); client.Proxy = _dnsServer.Proxy; client.PreferIPv6 = _dnsServer.PreferIPv6; client.Timeout = REFRESH_TIMEOUT; client.Retries = REFRESH_RETRIES; client.Concurrency = 1; DnsDatagram soaRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.SOA, DnsClass.IN) }); DnsDatagram soaResponse = await client.ResolveAsync(soaRequest); if (soaResponse.RCODE != DnsResponseCode.NoError) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received RCODE=" + soaResponse.RCODE.ToString() + " for '" + (_name == "" ? "<root>" : _name) + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(false); } if ((soaResponse.Answer.Count < 1) || (soaResponse.Answer[0].Type != DnsResourceRecordType.SOA) || !_name.Equals(soaResponse.Answer[0].Name, StringComparison.OrdinalIgnoreCase)) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received an empty response for SOA query for '" + (_name == "" ? "<root>" : _name) + "' stub zone refresh from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(false); } DnsResourceRecord currentSoaRecord = _entries[DnsResourceRecordType.SOA][0]; DnsResourceRecord receivedSoaRecord = soaResponse.Answer[0]; DnsSOARecord currentSoa = currentSoaRecord.RDATA as DnsSOARecord; DnsSOARecord receivedSoa = receivedSoaRecord.RDATA as DnsSOARecord; //compare using sequence space arithmetic if (!_resync && !currentSoa.IsZoneUpdateAvailable(receivedSoa)) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server successfully checked for '" + (_name == "" ? "<root>" : _name) + "' stub zone update from: " + soaResponse.Metadata.NameServerAddress.ToString()); } return(true); } //update available; do zone sync with TCP transport List <NameServerAddress> tcpNameServers = new List <NameServerAddress>(); foreach (NameServerAddress nameServer in nameServers) { tcpNameServers.Add(nameServer.ChangeProtocol(DnsTransportProtocol.Tcp)); } nameServers = tcpNameServers; client = new DnsClient(nameServers); client.Proxy = _dnsServer.Proxy; client.PreferIPv6 = _dnsServer.PreferIPv6; client.Timeout = REFRESH_TIMEOUT; client.Retries = REFRESH_RETRIES; client.Concurrency = 1; DnsDatagram nsRequest = new DnsDatagram(0, false, DnsOpcode.StandardQuery, false, false, false, false, false, false, DnsResponseCode.NoError, new DnsQuestionRecord[] { new DnsQuestionRecord(_name, DnsResourceRecordType.NS, DnsClass.IN) }); DnsDatagram nsResponse = await client.ResolveAsync(nsRequest); if (nsResponse.RCODE != DnsResponseCode.NoError) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received RCODE=" + nsResponse.RCODE.ToString() + " for '" + (_name == "" ? "<root>" : _name) + "' stub zone refresh from: " + nsResponse.Metadata.NameServerAddress.ToString()); } return(false); } if (nsResponse.Answer.Count < 1) { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server received an empty response for NS query for '" + (_name == "" ? "<root>" : _name) + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString()); } return(false); } //prepare sync records List <DnsResourceRecord> nsRecords = new List <DnsResourceRecord>(nsResponse.Answer.Count); foreach (DnsResourceRecord record in nsResponse.Answer) { if ((record.Type == DnsResourceRecordType.NS) && record.Name.Equals(_name)) { record.SyncGlueRecords(nsResponse.Additional); nsRecords.Add(record); } } receivedSoaRecord.CopyRecordInfoFrom(currentSoaRecord); //sync records _entries[DnsResourceRecordType.NS] = nsRecords; _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { receivedSoaRecord }; { LogManager log = _dnsServer.LogManager; if (log != null) { log.Write("DNS Server successfully refreshed '" + (_name == "" ? "<root>" : _name) + "' stub zone from: " + nsResponse.Metadata.NameServerAddress.ToString()); } } return(true); } catch (Exception ex) { LogManager log = _dnsServer.LogManager; if (log != null) { string strNameServers = null; foreach (NameServerAddress nameServer in nameServers) { if (strNameServers == null) { strNameServers = nameServer.ToString(); } else { strNameServers += ", " + nameServer.ToString(); } } log.Write("DNS Server failed to refresh '" + (_name == "" ? "<root>" : _name) + "' stub zone from: " + strNameServers); log.Write(ex); } return(false); } }
internal void CommitAndIncrementSerial(IReadOnlyList <DnsResourceRecord> deletedRecords = null, IReadOnlyList <DnsResourceRecord> addedRecords = null) { if (_internal) { return; } lock (_history) { DnsResourceRecord oldSoaRecord = _entries[DnsResourceRecordType.SOA][0]; DnsResourceRecord newSoaRecord; { DnsSOARecord soa = oldSoaRecord.RDATA as DnsSOARecord; uint serial = soa.Serial; if (serial < uint.MaxValue) { serial++; } else { serial = 1; } newSoaRecord = new DnsResourceRecord(oldSoaRecord.Name, oldSoaRecord.Type, oldSoaRecord.Class, oldSoaRecord.TtlValue, new DnsSOARecord(soa.PrimaryNameServer, soa.ResponsiblePerson, serial, soa.Refresh, soa.Retry, soa.Expire, soa.Minimum)) { Tag = oldSoaRecord.Tag }; oldSoaRecord.Tag = null; //remove RR info from old SOA to allow creating new RR info for it during SetDeletedOn() } //update SOA _entries[DnsResourceRecordType.SOA] = new DnsResourceRecord[] { newSoaRecord }; //start commit oldSoaRecord.SetDeletedOn(DateTime.UtcNow); //write removed _history.Add(oldSoaRecord); if (deletedRecords is not null) { foreach (DnsResourceRecord deletedRecord in deletedRecords) { if (deletedRecord.IsDisabled()) { continue; } _history.Add(deletedRecord); if (deletedRecord.Type == DnsResourceRecordType.NS) { _history.AddRange(deletedRecord.GetGlueRecords()); } } } //write added _history.Add(newSoaRecord); if (addedRecords is not null) { foreach (DnsResourceRecord addedRecord in addedRecords) { if (addedRecord.IsDisabled()) { continue; } _history.Add(addedRecord); if (addedRecord.Type == DnsResourceRecordType.NS) { _history.AddRange(addedRecord.GetGlueRecords()); } } } //end commit CleanupHistory(_history); } }