Esempio n. 1
0
        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);
                    }
                }
            }
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        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();
                    }
                }
            }
        }
Esempio n. 4
0
        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();
                }
            }
        }
Esempio n. 5
0
        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);
                }
            }
        }