RFC 8767

Serving Stale Data to Improve DNS Resiliency

๐Ÿ“… published March 2020, from ietf

RFC 8767: Serving Stale Data to Improve DNS Resiliency ๐ŸŽ€

okay bestie, let's get into it ๐Ÿ’– This is RFC 8767, and the title is literally Serving Stale Data to Improve DNS Resiliency ๐Ÿฆ‹ It was written by D. Lawrence from Oracle, W. Kumari (no affiliation is listed for him in the header), and P. Sood from Google ๐Ÿงš It was published in March 2020 ๐ŸŒธ and it's a Standards Track document, so it's an official Internet standard, no cap ๐Ÿ”ฅ Its ISSN is 2070-1721. It updates RFCs 1034, 1035, and 2181, and the header doesn't list any RFCs that it obsoletes ๐Ÿ‘‘


Abstract ๐Ÿ“

So the big idea is that recursive resolvers can use stale DNS data, which the doc calls serve-stale, when authoritative nameservers can't be reached to refresh expired data ๐Ÿ™ˆ The whole point is avoiding outages and making DNS tougher against DoS attacks, so attackers have less reason to bother ๐Ÿ’€ The doc updates the TTL definitions from RFCs 1034 and 1035 so data can stay in the cache past its TTL expiry ๐Ÿ“ It also updates RFC 2181 so values with the high-order bit set count as positive instead of 0, and it suggests a cap of 7 days โœจ


Status of This Memo ๐Ÿ“ฎ

This is an Internet Standards Track document ๐Ÿ”ฅ It's a product of the IETF, and it represents the consensus of the IETF community. It got public review and was approved for publication by the IESG. More info on Internet Standards is in Section 2 of RFC 7841 ๐Ÿ’œ For the current status, any errata, and how to send feedback, check https://www.rfc-editor.org/info/rfc8767 ๐ŸŒˆ


Copyright (c) 2020 IETF Trust and the persons identified as the document authors. All rights reserved. ๐ŸŽ€ This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) as they're in effect on the date of publication. Please read these carefully, because they spell out your rights and restrictions for this document ๐Ÿซถ Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License.


Table of Contents ๐Ÿ“š

1.  Introduction
2.  Terminology
3.  Background
4.  Standards Action
5.  Example Method
6.  Implementation Considerations
7.  Implementation Caveats
8.  Implementation Status
9.  EDNS Option
10. Security Considerations
11. Privacy Considerations
12. NAT Considerations
13. IANA Considerations
14. References
  14.1.  Normative References
  14.2.  Informative References
Acknowledgements
Authors' Addresses

1. Introduction โœจ

okay so traditionally, a DNS Resource Record's (RR's) TTL has been understood as the maximum number of seconds a record can be used before it has to be tossed ๐Ÿ—‘๏ธ That reading comes from [RFC1035], with clarifications in [RFC2181].

This doc expands the TTL definition so expired data can be used in the exceptional case where a recursive resolver can't refresh the info ๐Ÿ’… It's based on the observation that when authoritative answers are unavailable, outages can happen even when the underlying data those servers would return is usually unchanged ๐Ÿ˜ญ

We describe a method below for using stale data, and it balances the competing needs of resiliency and freshness โš–๏ธ

This doc updates the TTL definitions from [RFC1034] and [RFC1035] so data can be kept in the cache past TTL expiry ๐ŸŒธ It also updates [RFC2181] by interpreting values with the high-order bit set as positive rather than 0, and it suggests a cap of 7 days ๐Ÿ’œ


2. Terminology ๐Ÿ’…

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. ๐Ÿ”’

If you want a DNS glossary, [RFC8499] has your back ๐Ÿ“–


3. Background ๐Ÿง

There are a bunch of reasons an authoritative server can become unreachable, like Denial-of-Service (DoS) attacks, network issues, and so on ๐Ÿ’€ If a recursive server can't contact the authoritative servers for a query but still has relevant data that's aged past its TTL, that info can still be useful for making an answer. The vibe is "stale bread is better than no bread" ๐Ÿž

Here's what [RFC1035] says in Section 3.2.1: the TTL "specifies the time interval that the resource record may be cached before the source of the information should again be consulted." Then in Section 4.1.3, it adds that the TTL "specifies the time interval (in seconds) that the resource record may be cached before it should be discarded." ๐Ÿ“œ

Honestly, a natural English reading would make it pretty clear that records past their TTL expiration must not be used ๐Ÿ™ˆ BUT [RFC1035] came out before the more rigorous terminology of [RFC2119], which softened how "may" and "should" get interpreted. Plot twist ๐ŸŒ€

[RFC2181] set out to give "the precise definition of the Time to Live," but Section 8 of [RFC2181] was mostly about the numeric range of values rather than how data expires. It does close that section by noting, "The TTL specifies a maximum time to live, not a mandatory time to live." That wording doesn't contain BCP 14 key words [RFC2119], but it still gives the natural language vibe that data becomes unusable past TTL expiry ๐Ÿ‘€

As of this writing, several large-scale operators use stale data for answers in some way ๐ŸŒˆ A bunch of recursive resolver packages, including BIND, Knot Resolver, OpenDNS, and Unbound, give you options to use stale data. Apple macOS can also use stale data as part of the Happy Eyeballs algorithms in mDNSResponder โœจ The collective operational experience is that stale data can give significant benefit with minimal downside ๐ŸŽ€


4. Standards Action ๐Ÿ”ฅ

Here's the big moment ๐Ÿ‘‘ The definition of TTL in Sections 3.2.1 and 4.1.3 of [RFC1035] gets amended to read:

TTL  a 32-bit unsigned integer number of seconds that specifies the
     duration that the resource record MAY be cached before the
     source of the information MUST again be consulted.  Zero values
     are interpreted to mean that the RR can only be used for the
     transaction in progress, and should not be cached.  Values
     SHOULD be capped on the order of days to weeks, with a
     recommended cap of 604,800 seconds (7 days).  If the data is
     unable to be authoritatively refreshed when the TTL expires, the
     record MAY be used as though it is unexpired.  See Sections 5
     and 6 of [RFC8767] for details.

Interpreting values with the high-order bit set as positive, rather than 0, is a change from [RFC2181], and the reasoning behind it is explained in Section 6 ๐Ÿฆ‹ Suggesting a cap of 7 days, instead of the 68 years allowed by the full 31 bits in Section 8 of [RFC2181], matches what major modern DNS resolvers are doing right now ๐Ÿ’…

When a recursive resolver returns a response containing stale records, it MUST set the TTL of each expired record in the message to a value greater than 0. The RECOMMENDED value is 30 seconds ๐Ÿซถ See Section 6 for the explanation.

Answers from authoritative servers with a DNS response code of 0 (NoError) or 3 (NXDomain), and with the Authoritative Answer (AA) bit set, MUST be considered to have refreshed the data at the resolver. Answers with any other response code SHOULD be considered a failure to refresh the data, so any previous state stays intact. See Section 6 for a discussion. โœจ

Okay that's the core of it, bestie ๐Ÿ’– The rest of the spec builds on these rules, so keep them in your back pocket ๐Ÿงš

5. Example Method ๐Ÿ’…

okay so there's more than one way a recursive resolver could pull this resiliency move and still totally respect what the TTL is trying to say, which is basically "hey, time to refresh this data" ๐Ÿ•ฐ๏ธโœจ This section walks through one example method. It's giving "here's one good way," not "the only way" ๐Ÿซถ

In this example, four timers are the main characters ๐Ÿ‘‘ that decide how stale data gets used:

  • A client response timer, which is the max amount of time a recursive resolver should allow between getting a resolution request and sending its response. ๐Ÿ’–
  • A query resolution timer, which caps how much total time the resolver spends processing the query. โฑ๏ธ
  • A failure recheck timer, which limits how often a failed lookup gets tried again. ๐Ÿ”
  • A maximum stale timer, which caps how long records get kept past their expiration. ๐Ÿงบ

Most recursive resolvers already have the query resolution timer and, kind of, some version of a failure recheck timer ๐Ÿ™ˆ The client response timer and the maximum stale timer are the new faces in this mechanism ๐Ÿฆ‹

So when a recursive resolver gets a request, it should start the client response timer. This timer exists to avoid client timeouts ๐Ÿ’… It should be configurable, and the recommended value is 1.8 seconds. That's just under a common timeout value of 2 seconds, which still gives the resolver a fair shot at resolving the name ๐ŸŽ€

Next, the resolver checks its cache for any unexpired records that satisfy the request, and if it has them, it returns them โœจ If it finds no relevant unexpired data and the Recursion Desired flag is not set in the request, it should immediately return the response without checking the cache for expired records. Typically this response would be a referral to authoritative nameservers covering the zone, but the specifics are implementation dependent ๐Ÿงš

If iterative lookups are going to happen, then the failure recheck timer gets consulted ๐Ÿ‘€ Attempts to refresh from non-responsive or otherwise failing authoritative nameservers are recommended to happen no more frequently than every 30 seconds. If this request came in during that window, the cache may be immediately checked for stale data to satisfy the request ๐ŸŒธ

Outside the failure recheck timer's period, the resolver should start the query resolution timer and begin the iterative resolution process. This timer bounds the work the resolver does when it contacts external authorities, and it's commonly around 10 to 30 seconds โณ If this timer expires on a lookup that's still being processed, the resolution effort gets abandoned. Bye bye, lookup ๐Ÿ‘‹

If the answer still isn't fully figured out by the time the client response timer has elapsed, the resolver should check its cache to see whether there's expired data that would satisfy the request. If there is, it adds that data to the response message with a TTL greater than 0 (as specified in Section 4). Then the response goes to the client while the resolver keeps trying to refresh the data in the background ๐Ÿซถ๐Ÿ”ฅ

When no authorities can be reached during a resolution attempt, the resolver should attempt to refresh the delegation and restart the iterative lookup process with the remaining time on the query resolution timer. This resumption should be done only once per resolution effort. ๐Ÿšซ Only one do-over, bestie.

Outside the resolution process, the maximum stale timer handles cache management, and it's totally independent of the query resolution process ๐Ÿงบ This timer is conceptually different from the maximum cache TTL that exists in many resolvers. That one is a clamp on the TTL values received from authoritative servers, and it's recommended to be 7 days in the TTL definition in Section 4. The maximum stale timer should be configurable. It defines how long a record should be kept in the cache after it expires. The suggested value is between 1 and 3 days ๐Ÿ“…๐Ÿ’œ


6. Implementation Considerations ๐ŸŽ€

okay so this document mainly describes the issues behind serving stale data, and it intentionally does not give a formal algorithm ๐Ÿ™…โ€โ™€๏ธ The concept isn't overly complex, and the details are best left to resolver authors to build in their own codebases ๐Ÿ’ป Serve-stale is a local operation, so the variables don't need to match between deployments for interoperability to work. Still, we want to highlight how different implementation choices land, starting with the timers ๐Ÿง

The most obvious one is the maximum stale timer. If it's too large, it could cause excessive cache memory usage ๐Ÿ“ฆ๐Ÿ’€ But if it's too small, serve-stale gets less effective, because the record might not be in the cache when it's actually needed. Shorter values, even under a day, can handle the vast majority of outages ๐ŸŒˆ Longer values, as much as a week, give monitoring systems time to notice a resolution problem and give humans time to fix it. Operational experience has shown that sometimes the right people are hard to track down and, unfortunately, slow to remedy the situation ๐Ÿ˜ญ

Increased memory consumption could be mitigated by prioritizing the removal of stale records over non-expired records when the cache is running out of space โœจ Eviction strategies could also consider other factors, like the last time of use or the popularity of a record, so active but stale records can be kept around ๐Ÿฆ‹ A feature to manually flush only stale records could be useful too ๐Ÿงน

The client response timer is another variable that deserves some thought ๐Ÿ’… If this value is too short, there's a risk that stale answers get used even when the authoritative server is actually reachable but just slow. That can end up returning undesirable answers ๐Ÿ™ˆ On the flip side, waiting too long will hurt user experience ๐Ÿฅฒ

For the failure recheck timer, it's all about balance. You want responsiveness in detecting when authorities are available again, but you also don't want to burn extra resources on resolution ๐ŸŽฏ If this variable is set too large, stale answers may keep getting returned even after the authoritative server is reachable again. Per [RFC2308], Section 7, this should be no more than 5 minutes โฐ If this variable is too small, authoritative servers may get hit with a significant amount of excess traffic ๐Ÿšจ

Now, the TTL to set on stale records in the response. Historically, TTLs of 0 seconds have been problematic for some implementations, and negative values can't be effectively communicated to existing software ๐Ÿ™ƒ Other very short TTLs could lead to congestive collapse, since TTL-respecting clients would rapidly try to refresh. The recommended value of 30 seconds sidesteps those potential problems with no practical negative consequences ๐ŸŒท It also rate-limits further queries from any client that honors the TTL, such as a forwarding resolver ๐Ÿซถ

Next up, the change to treat a TTL with the high-order bit set as positive and then clamp it, instead of [RFC2181] treating it as zero. The reasoning here is basically engineering simplicity versus an inconsequential operational history ๐Ÿง  Negative TTLs never had a rational, intentional meaning that wouldn't have been satisfied by just sending 0 instead. And there was realistically no practical purpose for sending TTLs of 2^25 seconds (1 year) or more ๐Ÿ“† There's also no record of TTLs in the wild having the most significant bit set in the DNS Operations, Analysis, and Research Center's (DNS-OARC's) "Day in the Life" samples [DITL] ๐Ÿ‘€ With no apparent reason for operators to use them on purpose, that leaves either errors or non-standard experiments as the possible explanations for why such TTLs might show up. Neither one gives an obviously compelling reason why the leading bit set should be treated differently from having any of the next eleven bits set and then capped per Section 4 ๐Ÿ’–

Another implementation consideration is the use of stale nameserver addresses for lookups ๐Ÿ—บ๏ธ This gets called out explicitly because, in some resolvers, getting the addresses for nameservers is a separate path from a normal cache lookup. If authoritative server addresses can't be refreshed, resolution can still possibly succeed if the authoritative servers themselves are up ๐Ÿ™Œ For example, imagine an attack on a top-level domain that takes its nameservers offline. Serve-stale resolvers that had expired glue addresses for subdomains within that top-level domain could still resolve names within those subdomains, even ones they hadn't looked up before ๐Ÿงšโ€โ™€๏ธโœจ

The directive in Section 4 that only NoError and NXDomain responses should invalidate any previously associated answer comes from a simple fact: no other RCODEs a resolver normally runs into make any assertions about the name in the question or any data tied to it ๐Ÿง This matches existing resolver behavior, where a failed lookup (say, during prefetching) doesn't touch the existing cache state. Some authoritative server operators have said they'd prefer stale answers get used when their servers respond with errors like ServFail instead of giving true authoritative answers ๐Ÿฅน Implementers MAY decide to return stale answers in this situation ๐ŸŒˆ

Since the goal of serve-stale is to provide resiliency for all the obvious errors when refreshing data, these other RCODEs are treated as though they're equivalent to not getting an authoritative response ๐Ÿ’… NXDomain for a previously existing name might well be an error, but it isn't handled that way, because there's no effective way to tell apart operator intent in legitimate cases from error cases ๐Ÿ™ƒ

During discussion in the IETF, someone suggested that if all authorities return responses with an RCODE of Refused, it might be an explicit signal to take the zone down from servers that still have the zone's delegation pointed at them ๐Ÿค” But Refused is also overloaded and can mean multiple possible failures, some of which could be transient configuration problems ๐Ÿ˜ฌ Operational experience has shown that purposely returning Refused is a poor way to explicitly take down a zone, compared to either updating the delegation or returning NXDomain with a suitable SOA for extended negative caching ๐Ÿ“ Even so, Implementers MAY consider whether to treat all authorities returning Refused as preempting the use of stale data ๐Ÿซถ๐Ÿ’œ

7. Implementation Caveats ๐ŸŽ€

Okay bestie, stale data is only okay to use when refreshing has failed ๐Ÿ’…. That's the original design of the DNS, and it's what operators expect. If a resolver always served stale data right away and only tried refreshing after the client already had its response, it would keep handing out data it could've easily refreshed ๐Ÿ˜ญ. Modern resolvers use prefetching and request coalescing to stay efficient ๐Ÿงš, so every client request doesn't have to kick off a brand-new lookup when stale data is sitting there. What matters is that a good-faith effort was made recently to refresh the stale data before any client gets it โœจ.

It's also super important to keep the resolution attempt going after the stale response has been sent, until the query resolution timeout ๐Ÿฆ‹. Some pathological resolutions take many seconds to succeed because they're dealing with unavailable servers, bad networks, and other problems. If you stopped as soon as the expired response went out, those answers would never get refreshed ๐Ÿ™ˆ.

The rule against using data with a 0-second TTL beyond the current transaction also explicitly covers stale fallback ๐Ÿšซ. That data isn't cached at all, so it's not usable as stale data either ๐Ÿ’€.

Be aware that Canonical Name (CNAME) and DNAME records [RFC6672] mingled in the expired cache with other records at the same owner name can cause surprising results ๐Ÿ‘€. This was observed with an early BIND implementation when a hostname changed from an IPv4 Address (A) record to a CNAME. That version of BIND didn't evict other types from the cache when a CNAME came in, which usually isn't a big deal. But after both records expired and the authorities went down, the stale fallback returned the older A record instead of the newer CNAME ๐Ÿ˜ฑ.

8. Implementation Status ๐ŸŒˆ

The algorithm described in Section 5 was originally implemented as a patch to BIND 9.7.0 ๐Ÿ”ฅ. It's been running on Akamai's production network since 2011, and it smoothed over transient failures and longer outages that would otherwise have turned into major incidents ๐Ÿ‘‘. The patch was contributed to the Internet Systems Consortium, and the functionality is now in BIND 9.12 and later through the options stale-answer-enable, stale-answer-ttl, and max-stale-ttl โœจ.

Unbound has a similar feature for serving stale answers. It'll respond with stale data immediately if it recently tried and failed to refresh the answer through prefetching ๐Ÿงš. Starting from version 1.10.0, Unbound can also be configured to follow the algorithm described in Section 5. Both behaviors can be configured and fine-tuned with the available serve-expired-* options ๐Ÿ’–.

Knot Resolver has a demo module here: https://knot-resolver.readthedocs.io/en/stable/modules-serve_stale.html ๐Ÿฆ‹.

Apple's system resolvers are also known to use stale answers, but the details aren't readily available ๐Ÿคทโ€โ™€๏ธ.

In the research paper "When the Dike Breaks: Dissecting DNS Defenses During DDoS" [DikeBreaks], the authors detected some use of stale answers by resolvers when authorities came under attack ๐Ÿง. Their results suggest that more widespread adoption of the technique would significantly improve resiliency for the large number of requests that fail or take abnormally long to resolve during an attack. Iconic research, honestly ๐Ÿ”ฅ.

9. EDNS Option ๐Ÿงพ

During the IETF discussion of serve-stale, someone suggested that an EDNS option [RFC6891] should be available ๐Ÿ’ญ. One proposal was to use it to opt in to getting data that might be stale. Another was to signal when stale data had been used in a response.

The opt-in use case was rejected, because the technique was meant to be immediately useful for improving DNS resiliency for all clients ๐Ÿ™…โ€โ™€๏ธ.

The reporting case was ultimately rejected too. Even the simpler version of the proposed option was still too much bother to implement for too little perceived value ๐Ÿ˜‚.

10. Security Considerations ๐Ÿ”

Okay, this section is serious, so please pay attention ๐Ÿšจ. The most obvious security issue is the increased likelihood of DNSSEC validation failures when stale data is used, because signatures could be returned outside their validity period ๐Ÿ˜ฌ. Stale negative records can also increase the time window where newly published TLSA or DS RRs may not be used because of cached NSEC or NSEC3 records. These scenarios only become an issue if the authoritative servers are unreachable, which is the only time the techniques in this document are used. So serve-stale doesn't introduce a new failure in place of what would otherwise have been a success ๐Ÿซถ.

Bad actors have also been known to use DNS caches to keep records alive even after their authorities have gone away ๐Ÿ‘ป. The serve-stale feature potentially makes that attack easier, though it doesn't introduce a new risk. Attackers could also combine this with a DDoS attack on authoritative servers with the explicit goal of having stale information cached for longer. But if attackers have that kind of capacity, they probably could do a lot worse than prolonging the life of old data ๐Ÿ’€.

In [CloudStrife], it was demonstrated how stale DNS data can be used to co-opt security. Those are hostnames pointing to addresses that the name's owner no longer uses, and they can be abused to get domain-validated certificates fraudulently issued to an attacker ๐Ÿ˜ฑ. This document doesn't create a new vulnerability in this area, but it does potentially enlarge the window in which such an attack could be made. A proposed mitigation is that certificate authorities should fully look up each name starting at the DNS root for every name lookup. Alternatively, certificate authorities should use a resolver that isn't serving stale data ๐Ÿ›ก๏ธ.

11. Privacy Considerations ๐Ÿฆ‹

This document doesn't add any practical new privacy issues ๐Ÿซง.

12. NAT Considerations ๐ŸŒธ

The method described here isn't affected by the use of NAT devices ๐Ÿ’ซ.

13. IANA Considerations ๐Ÿ“‹

This document has no IANA actions ๐Ÿ™Œ.

14. References ๐Ÿ“š

Here are the receipts, every single one ๐Ÿงพ.

14.1. Normative References

[RFC1034]  Mockapetris, P., "Domain names - concepts and facilities",
           STD 13, RFC 1034, DOI 10.17487/RFC1034, November 1987,
           <https://www.rfc-editor.org/info/rfc1034>.

[RFC1035]  Mockapetris, P., "Domain names - implementation and
           specification", STD 13, RFC 1035, DOI 10.17487/RFC1035,
           November 1987, <https://www.rfc-editor.org/info/rfc1035>.

[RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
           Requirement Levels", BCP 14, RFC 2119,
           DOI 10.17487/RFC2119, March 1997,
           <https://www.rfc-editor.org/info/rfc2119>.

[RFC2181]  Elz, R. and R. Bush, "Clarifications to the DNS
           Specification", RFC 2181, DOI 10.17487/RFC2181, July 1997,
           <https://www.rfc-editor.org/info/rfc2181>.

[RFC2308]  Andrews, M., "Negative Caching of DNS Queries (DNS
           NCACHE)", RFC 2308, DOI 10.17487/RFC2308, March 1998,
           <https://www.rfc-editor.org/info/rfc2308>.

[RFC8174]  Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
           2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
           May 2017, <https://www.rfc-editor.org/info/rfc8174>.

14.2. Informative References

[CloudStrife]
           Borgolte, K., Fiebig, T., Hao, S., Kruegel, C., and G.
           Vigna, "Cloud Strife: Mitigating the Security Risks of
           Domain-Validated Certificates",
           DOI 10.1145/3232755.3232859, ACM 2018 Applied Networking
           Research Workshop, July 2018, <https://www.ndss-
           symposium.org/wp-content/uploads/2018/02/ndss2018_06A-
           4_Borgolte_paper.pdf>.

[DikeBreaks]
           Moura, G.C.M., Heidemann, J., Mรผller, M., Schmidt, R. de
           O., and M. Davids, "When the Dike Breaks: Dissecting DNS
           Defenses During DDoS", DOI 10.1145/3278532.3278534,
           ACM 2018 Internet Measurement Conference, October 2018,
           <https://www.isi.edu/~johnh/PAPERS/Moura18b.pdf>.

[DITL]     DNS-OARC, "DITL Traces and Analysis", January 2018,
           <https://www.dns-oarc.net/oarc/data/ditl>.

[RFC6672]  Rose, S. and W. Wijngaards, "DNAME Redirection in the
           DNS", RFC 6672, DOI 10.17487/RFC6672, June 2012,
           <https://www.rfc-editor.org/info/rfc6672>.

[RFC6891]  Damas, J., Graff, M., and P. Vixie, "Extension Mechanisms
           for DNS (EDNS(0))", STD 75, RFC 6891,
           DOI 10.17487/RFC6891, April 2013,
           <https://www.rfc-editor.org/info/rfc6891>.

[RFC8499]  Hoffman, P., Sullivan, A., and K. Fujiwara, "DNS
           Terminology", BCP 219, RFC 8499, DOI 10.17487/RFC8499,
           January 2019, <https://www.rfc-editor.org/info/rfc8499>.

Acknowledgements ๐Ÿซถ

The authors wish to thank Brian Carpenter, Vladimir Cunat, Robert Edmonds, Tony Finch, Bob Harold, Tatuya Jinmei, Matti Klock, Jason Moreau, Giovane Moura, Jean Roy, Mukund Sivaraman, Davey Song, Paul Vixie, Ralf Weber, and Paul Wouters for their review and feedback ๐Ÿ’œ. Paul Hoffman deserves special thanks for submitting a number of Pull Requests ๐Ÿ‘‘.

Thank you also to the following members of the IESG for their final review: Roman Danyliw, Benjamin Kaduk, Suresh Krishnan, Mirja Kรผhlewind, and Adam Roach ๐ŸŒท.

Authors' Addresses ๐Ÿ’Œ

David C Lawrence
Oracle

Email: tale@dd.org


Warren "Ace" Kumari
Google
1600 Amphitheatre Parkway
Mountain View, CA 94043
United States of America

Email: warren@kumari.net


Puneet Sood
Google

Email: puneets@google.com
๐Ÿ“ฆ where this page comes from