예제 #1
0
 public void RemoveExpiredRecords(bool serveStale)
 {
     foreach (KeyValuePair <DnsResourceRecordType, IReadOnlyList <DnsResourceRecord> > entry in _entries)
     {
         if (DnsResourceRecord.IsRRSetExpired(entry.Value, serveStale))
         {
             _entries.TryRemove(entry.Key, out _); //RR Set is expired; remove entry
         }
     }
 }
예제 #2
0
        public int RemoveExpiredRecords(bool serveStale)
        {
            int removedEntries = 0;

            foreach (KeyValuePair <DnsResourceRecordType, IReadOnlyList <DnsResourceRecord> > entry in _entries)
            {
                if (DnsResourceRecord.IsRRSetExpired(entry.Value, serveStale))
                {
                    if (_entries.TryRemove(entry.Key, out _)) //RR Set is expired; remove entry
                    {
                        removedEntries++;
                    }
                }
            }

            return(removedEntries);
        }
예제 #3
0
        public void SetRecords(DnsResourceRecordType type, IReadOnlyList <DnsResourceRecord> records, bool serveStale)
        {
            bool isFailureRecord = (records.Count > 0) && (records[0].RDATA is DnsCache.DnsSpecialCacheRecord splRecord) && splRecord.IsFailure;

            if (isFailureRecord)
            {
                //call trying to cache failure record
                if (_entries.TryGetValue(type, out IReadOnlyList <DnsResourceRecord> existingRecords))
                {
                    if ((existingRecords.Count > 0) && !(existingRecords[0].RDATA is DnsCache.DnsSpecialCacheRecord existingSplRecord && existingSplRecord.IsFailure) && !DnsResourceRecord.IsRRSetExpired(existingRecords, serveStale))
                    {
                        return; //skip to avoid overwriting a useful record with a failure record
                    }
                }
            }

            //set records
            _entries[type] = records;

            if (serveStale && !isFailureRecord)
            {
                //remove stale CNAME entry only when serve stale is enabled
                //making sure current record is not a failure record causing removal of useful stale CNAME record
                switch (type)
                {
                case DnsResourceRecordType.CNAME:
                case DnsResourceRecordType.SOA:
                case DnsResourceRecordType.NS:
                    //do nothing
                    break;

                default:
                    //remove stale CNAME entry since current new entry type overlaps any existing CNAME entry in cache
                    //keeping both entries will create issue with serve stale implementation since stale CNAME entry will be always returned

                    if (_entries.TryGetValue(DnsResourceRecordType.CNAME, out IReadOnlyList <DnsResourceRecord> existingCNAMERecords))
                    {
                        if ((existingCNAMERecords.Count > 0) && (existingCNAMERecords[0].RDATA is DnsCNAMERecord) && existingCNAMERecords[0].IsStale)
                        {
                            //delete CNAME entry only when it contains stale DnsCNAMERecord RDATA and not special cache records
                            _entries.TryRemove(DnsResourceRecordType.CNAME, out _);
                        }
                    }
                    break;
                }
            }
        }
예제 #4
0
        public bool SetRecords(DnsResourceRecordType type, IReadOnlyList <DnsResourceRecord> records, bool serveStale)
        {
            bool isFailureRecord = false;

            if (records.Count > 0)
            {
                if (records[0].RDATA is DnsCache.DnsSpecialCacheRecord splRecord)
                {
                    if (splRecord.IsFailureOrBadCache)
                    {
                        //call trying to cache failure record
                        isFailureRecord = true;

                        if (_entries.TryGetValue(type, out IReadOnlyList <DnsResourceRecord> existingRecords))
                        {
                            if ((existingRecords.Count > 0) && !(existingRecords[0].RDATA is DnsCache.DnsSpecialCacheRecord existingSplRecord && existingSplRecord.IsFailureOrBadCache) && !DnsResourceRecord.IsRRSetExpired(existingRecords, serveStale))
                            {
                                return(false); //skip to avoid overwriting a useful record with a failure record
                            }
                        }
                    }
                }
                else if ((type == DnsResourceRecordType.NS) && (records[0].RDATA is DnsNSRecordData ns) && !ns.IsParentSideTtlSet)
                {
                    //for ns revalidation
                    if (_entries.TryGetValue(DnsResourceRecordType.NS, out IReadOnlyList <DnsResourceRecord> existingNSRecords))
                    {
                        if ((existingNSRecords.Count > 0) && (existingNSRecords[0].RDATA is DnsNSRecordData existingNS) && existingNS.IsParentSideTtlSet)
                        {
                            uint parentSideTtl = existingNS.ParentSideTtl;

                            foreach (DnsResourceRecord record in records)
                            {
                                (record.RDATA as DnsNSRecordData).ParentSideTtl = parentSideTtl;
                            }
                        }
                    }
                }
            }

            //set last used date time
            DateTime utcNow = DateTime.UtcNow;

            foreach (DnsResourceRecord record in records)
            {
                record.GetRecordInfo().LastUsedOn = utcNow;
            }

            //set records
            bool added = true;

            _entries.AddOrUpdate(type, records, delegate(DnsResourceRecordType key, IReadOnlyList <DnsResourceRecord> existingRecords)
            {
                added = false;
                return(records);
            });

            if (serveStale && !isFailureRecord)
            {
                //remove stale CNAME entry only when serve stale is enabled
                //making sure current record is not a failure record causing removal of useful stale CNAME record
                switch (type)
                {
                case DnsResourceRecordType.CNAME:
                case DnsResourceRecordType.SOA:
                case DnsResourceRecordType.NS:
                case DnsResourceRecordType.DS:
                    //do nothing
                    break;

                default:
                    //remove stale CNAME entry since current new entry type overlaps any existing CNAME entry in cache
                    //keeping both entries will create issue with serve stale implementation since stale CNAME entry will be always returned

                    if (_entries.TryGetValue(DnsResourceRecordType.CNAME, out IReadOnlyList <DnsResourceRecord> existingCNAMERecords))
                    {
                        if ((existingCNAMERecords.Count > 0) && (existingCNAMERecords[0].RDATA is DnsCNAMERecordData) && existingCNAMERecords[0].IsStale)
                        {
                            //delete CNAME entry only when it contains stale DnsCNAMERecord RDATA and not special cache records
                            _entries.TryRemove(DnsResourceRecordType.CNAME, out _);
                        }
                    }
                    break;
                }
            }

            return(added);
        }