From e007ae3ecbc2f642f4e11059376e6b649bba155f Mon Sep 17 00:00:00 2001 From: Shreyas Zare Date: Sat, 24 Sep 2022 11:48:01 +0530 Subject: [PATCH] CacheZoneManager: Updated Query() to correctly detect if a record is stale and add extended error info. --- .../Dns/ZoneManagers/CacheZoneManager.cs | 53 ++++++++++++++----- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/DnsServerCore/Dns/ZoneManagers/CacheZoneManager.cs b/DnsServerCore/Dns/ZoneManagers/CacheZoneManager.cs index f18f3407..8e396333 100644 --- a/DnsServerCore/Dns/ZoneManagers/CacheZoneManager.cs +++ b/DnsServerCore/Dns/ZoneManagers/CacheZoneManager.cs @@ -578,8 +578,6 @@ namespace DnsServerCore.Dns.ZoneManagers } } - IReadOnlyList specialOptions = null; - if (serveStaleAndResetExpiry) { if (firstRR.IsStale) @@ -593,20 +591,27 @@ namespace DnsServerCore.Dns.ZoneManagers record.ResetExpiry(30); //reset expiry by 30 seconds so that resolver tries again only after 30 seconds as per draft-ietf-dnsop-serve-stale-04 } } - - if (dnsSpecialCacheRecord.RCODE == DnsResponseCode.NxDomain) - { - List newOptions = new List(dnsSpecialCacheRecord.EDnsOptions.Count + 1); - - newOptions.AddRange(dnsSpecialCacheRecord.EDnsOptions); - newOptions.Add(new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleNxDomainAnswer, null))); - - specialOptions = newOptions; - } } - if (specialOptions is null) + IReadOnlyList specialOptions; + + if (firstRR.WasExpiryReset) + { + List newOptions = new List(dnsSpecialCacheRecord.EDnsOptions.Count + 1); + + newOptions.AddRange(dnsSpecialCacheRecord.EDnsOptions); + + if (dnsSpecialCacheRecord.RCODE == DnsResponseCode.NxDomain) + newOptions.Add(new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleNxDomainAnswer, null))); + else + newOptions.Add(new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleAnswer, null))); + + specialOptions = newOptions; + } + else + { specialOptions = dnsSpecialCacheRecord.EDnsOptions; + } if (request.DnssecOk) { @@ -695,6 +700,17 @@ namespace DnsServerCore.Dns.ZoneManagers options = new EDnsOption[] { new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleAnswer, null)) }; } + else + { + foreach (DnsResourceRecord record in answer) + { + if (record.WasExpiryReset) + { + options = new EDnsOption[] { new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleAnswer, null)) }; + break; + } + } + } return new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, true, answer[0].DnssecStatus == DnssecStatus.Secure, request.CheckingDisabled, DnsResponseCode.NoError, request.Question, answer, authority, additional, request.EDNS is null ? ushort.MinValue : _dnsServer.UdpPayloadSize, ednsFlags, options); } @@ -745,6 +761,17 @@ namespace DnsServerCore.Dns.ZoneManagers options = new EDnsOption[] { new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleAnswer, null)) }; } + else + { + foreach (DnsResourceRecord record in answer) + { + if (record.WasExpiryReset) + { + options = new EDnsOption[] { new EDnsOption(EDnsOptionCode.EXTENDED_DNS_ERROR, new EDnsExtendedDnsErrorOption(EDnsExtendedDnsErrorCode.StaleAnswer, null)) }; + break; + } + } + } return new DnsDatagram(request.Identifier, true, DnsOpcode.StandardQuery, false, false, request.RecursionDesired, true, answer[0].DnssecStatus == DnssecStatus.Secure, request.CheckingDisabled, rCode, request.Question, answer, authority, null, request.EDNS is null ? ushort.MinValue : _dnsServer.UdpPayloadSize, ednsFlags, options); }