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 } } }
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); }
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; } } }
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); }