protected override void CacheRecords(IReadOnlyList <DnsResourceRecord> resourceRecords) { if (resourceRecords.Count == 1) { CacheZone zone = _root.GetOrAdd(resourceRecords[0].Name, delegate(string key) { return(new CacheZone(resourceRecords[0].Name)); }); zone.SetRecords(resourceRecords[0].Type, resourceRecords); } else { Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByDomainRecords = DnsResourceRecord.GroupRecords(resourceRecords); //add grouped records foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByTypeRecords in groupedByDomainRecords) { CacheZone zone = _root.GetOrAdd(groupedByTypeRecords.Key, delegate(string key) { return(new CacheZone(groupedByTypeRecords.Key)); }); foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { zone.SetRecords(groupedRecords.Key, groupedRecords.Value); } } } }
public void SyncRecords(string domain, IReadOnlyList <DnsResourceRecord> syncRecords, IReadOnlyList <DnsResourceRecord> additionalRecords = null, bool dontRemoveRecords = false) { List <DnsResourceRecord> newRecords = new List <DnsResourceRecord>(syncRecords.Count); List <DnsResourceRecord> allGlueRecords = new List <DnsResourceRecord>(); if (additionalRecords != null) { foreach (DnsResourceRecord additionalRecord in additionalRecords) { if (!allGlueRecords.Contains(additionalRecord)) { allGlueRecords.Add(additionalRecord); } } } int i = 0; if ((syncRecords.Count > 1) && (syncRecords[0].Type == DnsResourceRecordType.SOA) && (syncRecords[syncRecords.Count - 1].Type == DnsResourceRecordType.SOA)) { i = 1; //skip first SOA in AXFR } if (domain.Length == 0) { //root zone case for (; i < syncRecords.Count; i++) { DnsResourceRecord record = syncRecords[i]; switch (record.Type) { case DnsResourceRecordType.A: case DnsResourceRecordType.AAAA: if (!allGlueRecords.Contains(record)) { allGlueRecords.Add(record); } break; default: newRecords.Add(record); break; } } } else { for (; i < syncRecords.Count; i++) { DnsResourceRecord record = syncRecords[i]; if (record.Name.Equals(domain, StringComparison.OrdinalIgnoreCase) || record.Name.EndsWith("." + domain, StringComparison.OrdinalIgnoreCase)) { newRecords.Add(record); } else if (!allGlueRecords.Contains(record)) { allGlueRecords.Add(record); } } } if (allGlueRecords.Count > 0) { foreach (DnsResourceRecord record in newRecords) { switch (record.Type) { case DnsResourceRecordType.NS: record.SyncGlueRecords(allGlueRecords); break; } } } List <DnsResourceRecord> oldRecords = ListAllRecords(domain); Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > newRecordsGroupedByDomain = DnsResourceRecord.GroupRecords(newRecords); Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > oldRecordsGroupedByDomain = DnsResourceRecord.GroupRecords(oldRecords); if (!dontRemoveRecords) { //remove domains that do not exists in new records foreach (string oldDomain in oldRecordsGroupedByDomain.Keys) { if (!newRecordsGroupedByDomain.ContainsKey(oldDomain)) { _root.TryRemove(oldDomain, out _); } } } //sync new records foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > newEntries in newRecordsGroupedByDomain) { AuthZone zone = GetOrAddSubDomainZone(newEntries.Key); if (zone.Name.Equals(domain, StringComparison.OrdinalIgnoreCase)) { zone.SyncRecords(newEntries.Value, dontRemoveRecords); } else if (zone is SubDomainZone) { zone.SyncRecords(newEntries.Value, dontRemoveRecords); } } }
private void LoadRecords(AuthZone authZone, IReadOnlyList <DnsResourceRecord> records) { Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByDomainRecords = DnsResourceRecord.GroupRecords(records); foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByTypeRecords in groupedByDomainRecords) { if (authZone.Name.Equals(groupedByTypeRecords.Key, StringComparison.OrdinalIgnoreCase)) { foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { authZone.LoadRecords(groupedRecords.Key, groupedRecords.Value); } } else { AuthZone zone = GetOrAddSubDomainZone(groupedByTypeRecords.Key); if (zone is SubDomainZone) { foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { zone.LoadRecords(groupedRecords.Key, groupedRecords.Value); } (zone as SubDomainZone).AutoUpdateState(); } } } }
private void LoadRecords(IReadOnlyList <DnsResourceRecord> records) { Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByDomainRecords = DnsResourceRecord.GroupRecords(records); foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByTypeRecords in groupedByDomainRecords) { AuthZone zone = GetOrAddZone(groupedByTypeRecords.Key); foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { zone.LoadRecords(groupedRecords.Key, groupedRecords.Value); } if (zone is SubDomainZone) { (zone as SubDomainZone).AutoUpdateState(); } } }
protected override void CacheRecords(IReadOnlyList <DnsResourceRecord> resourceRecords) { //read and set glue records from base class foreach (DnsResourceRecord resourceRecord in resourceRecords) { IReadOnlyList <DnsResourceRecord> glueRecords = GetGlueRecordsFrom(resourceRecord); if (glueRecords.Count > 0) { resourceRecord.SetGlueRecords(glueRecords); } } if (resourceRecords.Count == 1) { if (resourceRecords[0].Name.Contains('*')) { return; } CacheZone zone = _root.GetOrAdd(resourceRecords[0].Name, delegate(string key) { return(new CacheZone(resourceRecords[0].Name, 1)); }); zone.SetRecords(resourceRecords[0].Type, resourceRecords, _dnsServer.ServeStale); } else { Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByDomainRecords = DnsResourceRecord.GroupRecords(resourceRecords); bool serveStale = _dnsServer.ServeStale; //add grouped records foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByTypeRecords in groupedByDomainRecords) { if (groupedByTypeRecords.Key.Contains('*')) { continue; } CacheZone zone = _root.GetOrAdd(groupedByTypeRecords.Key, delegate(string key) { return(new CacheZone(groupedByTypeRecords.Key, groupedByTypeRecords.Value.Count)); }); foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { zone.SetRecords(groupedRecords.Key, groupedRecords.Value, serveStale); } } } }
protected override void CacheRecords(IReadOnlyList <DnsResourceRecord> resourceRecords) { List <DnsResourceRecord> dnameRecords = null; //read and set glue records from base class; also collect any DNAME records found foreach (DnsResourceRecord resourceRecord in resourceRecords) { IReadOnlyList <DnsResourceRecord> glueRecords = GetGlueRecordsFrom(resourceRecord); IReadOnlyList <DnsResourceRecord> rrsigRecords = GetRRSIGRecordsFrom(resourceRecord); IReadOnlyList <DnsResourceRecord> nsecRecords = GetNSECRecordsFrom(resourceRecord); if ((glueRecords is not null) || (rrsigRecords is not null) || (nsecRecords is not null)) { DnsResourceRecordInfo rrInfo = resourceRecord.GetRecordInfo(); rrInfo.GlueRecords = glueRecords; rrInfo.RRSIGRecords = rrsigRecords; rrInfo.NSECRecords = nsecRecords; if (glueRecords is not null) { foreach (DnsResourceRecord glueRecord in glueRecords) { IReadOnlyList <DnsResourceRecord> glueRRSIGRecords = GetRRSIGRecordsFrom(glueRecord); if (glueRRSIGRecords is not null) { glueRecord.GetRecordInfo().RRSIGRecords = glueRRSIGRecords; } } } if (nsecRecords is not null) { foreach (DnsResourceRecord nsecRecord in nsecRecords) { IReadOnlyList <DnsResourceRecord> nsecRRSIGRecords = GetRRSIGRecordsFrom(nsecRecord); if (nsecRRSIGRecords is not null) { nsecRecord.GetRecordInfo().RRSIGRecords = nsecRRSIGRecords; } } } } if (resourceRecord.Type == DnsResourceRecordType.DNAME) { if (dnameRecords is null) { dnameRecords = new List <DnsResourceRecord>(1); } dnameRecords.Add(resourceRecord); } } if (resourceRecords.Count == 1) { DnsResourceRecord resourceRecord = resourceRecords[0]; CacheZone zone = _root.GetOrAdd(resourceRecord.Name, delegate(string key) { return(new CacheZone(resourceRecord.Name, 1)); }); if (zone.SetRecords(resourceRecord.Type, resourceRecords, _dnsServer.ServeStale)) { Interlocked.Increment(ref _totalEntries); } } else { Dictionary <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByDomainRecords = DnsResourceRecord.GroupRecords(resourceRecords); bool serveStale = _dnsServer.ServeStale; int addedEntries = 0; //add grouped records foreach (KeyValuePair <string, Dictionary <DnsResourceRecordType, List <DnsResourceRecord> > > groupedByTypeRecords in groupedByDomainRecords) { if (dnameRecords is not null) { bool foundSynthesizedCNAME = false; foreach (DnsResourceRecord dnameRecord in dnameRecords) { if (groupedByTypeRecords.Key.EndsWith("." + dnameRecord.Name, StringComparison.OrdinalIgnoreCase)) { foundSynthesizedCNAME = true; break; } } if (foundSynthesizedCNAME) { continue; //do not cache synthesized CNAME } } CacheZone zone = _root.GetOrAdd(groupedByTypeRecords.Key, delegate(string key) { return(new CacheZone(groupedByTypeRecords.Key, groupedByTypeRecords.Value.Count)); }); foreach (KeyValuePair <DnsResourceRecordType, List <DnsResourceRecord> > groupedRecords in groupedByTypeRecords.Value) { if (zone.SetRecords(groupedRecords.Key, groupedRecords.Value, serveStale)) { addedEntries++; } } } if (addedEntries > 0) { Interlocked.Add(ref _totalEntries, addedEntries); } } }