[PR #3372] [MERGED] Cache negative responses in the ResponseCache #3786

Closed
opened 2026-03-16 12:02:40 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hickory-dns/hickory-dns/pull/3372
Author: @marcus0x62
Created: 12/3/2025
Status: Merged
Merged: 12/15/2025
Merged by: @marcus0x62

Base: mainHead: recursor-cache-negative-responses


📝 Commits (4)

  • 4012071 proto: add decrement_ttl function to Record
  • 2d12bc7 test-support: cache queries for inspection by callers
  • fd06306 resolver: update NoRecords TTLs in negative ResponseCache
  • 4520360 resolver: cache nxdomain responses in recursor

📊 Changes

5 files changed (+271 additions, -10 deletions)

View changed files

📝 crates/proto/src/rr/resource.rs (+7 -0)
📝 crates/resolver/src/cache.rs (+150 -4)
📝 crates/resolver/src/recursor/handle.rs (+4 -3)
📝 crates/resolver/src/recursor/tests.rs (+62 -0)
📝 tests/test-support/src/lib.rs (+48 -3)

📄 Description

This adds support for caching negative responses for no data and nxdomain responses in the recursor ResponseCache. Note that it does not implement caching for SERVFAIL responses (we'll have to index by server IP in the cache for those -- RFC 2308 7.1)

@divergentdave in #2595 you added this comment:

Special consideration will be required for NSEC RRs on either side of a zone cut. From RFC 4035 section 5.2:

Note that, for a signed delegation, there are two NSEC RRs associated with the delegated name. One NSEC RR resides in the parent zone and can be used to prove whether a DS RRset exists for the delegated name. The second NSEC RR resides in the child zone and identifies which RRsets are present at the apex of the child zone. ... A security-aware resolver MUST use the parent NSEC RR when attempting to prove that a DS RRset does not exist.

I don't we have to worry about using an NSEC record from the child zone -- the RecursorDnsHandle will only send requests for DS records to the parent of the name being queried:

    let zone = match query.query_type() {
       RecordType::DS => query.name().base_name(),
       _ => query.name().clone(),
   };

so the NSEC RR used to validate a non-existent DS record should come from that query to the name servers for the parent zone. Our zone cut detection needs improvement in general, and certainly in the case of DS records -- the parent name might not be the delegation point -- but that feels like a change unrelated to #2595. Let me know your thoughts.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/hickory-dns/hickory-dns/pull/3372 **Author:** [@marcus0x62](https://github.com/marcus0x62) **Created:** 12/3/2025 **Status:** ✅ Merged **Merged:** 12/15/2025 **Merged by:** [@marcus0x62](https://github.com/marcus0x62) **Base:** `main` ← **Head:** `recursor-cache-negative-responses` --- ### 📝 Commits (4) - [`4012071`](https://github.com/hickory-dns/hickory-dns/commit/40120718d1efea7c791b0e1f03e8e5157c1be4f1) proto: add decrement_ttl function to Record - [`2d12bc7`](https://github.com/hickory-dns/hickory-dns/commit/2d12bc7d1233d76bff01b6677cf7b243cc946982) test-support: cache queries for inspection by callers - [`fd06306`](https://github.com/hickory-dns/hickory-dns/commit/fd06306842ea3c6dd838757af28cd028c7219b1a) resolver: update NoRecords TTLs in negative ResponseCache - [`4520360`](https://github.com/hickory-dns/hickory-dns/commit/45203606615a70c7861507463a29a3aaac773b11) resolver: cache nxdomain responses in recursor ### 📊 Changes **5 files changed** (+271 additions, -10 deletions) <details> <summary>View changed files</summary> 📝 `crates/proto/src/rr/resource.rs` (+7 -0) 📝 `crates/resolver/src/cache.rs` (+150 -4) 📝 `crates/resolver/src/recursor/handle.rs` (+4 -3) 📝 `crates/resolver/src/recursor/tests.rs` (+62 -0) 📝 `tests/test-support/src/lib.rs` (+48 -3) </details> ### 📄 Description This adds support for caching negative responses for no data and nxdomain responses in the recursor ResponseCache. Note that it does not implement caching for SERVFAIL responses (we'll have to index by server IP in the cache for those -- RFC 2308 7.1) @divergentdave in #2595 you added this comment: > Special consideration will be required for NSEC RRs on either side of a zone cut. From RFC 4035 section 5.2: > > Note that, for a signed delegation, there are two NSEC RRs associated with the delegated name. One NSEC RR resides in the parent zone and can be used to prove whether a DS RRset exists for the delegated name. The second NSEC RR resides in the child zone and identifies which RRsets are present at the apex of the child zone. ... A security-aware resolver MUST use the parent NSEC RR when attempting to prove that a DS RRset does not exist. I don't we have to worry about using an NSEC record from the child zone -- the RecursorDnsHandle will only send requests for DS records to the parent of the name being queried: > let zone = match query.query_type() { > RecordType::DS => query.name().base_name(), > _ => query.name().clone(), > }; so the NSEC RR used to validate a non-existent DS record should come from that query to the name servers for the parent zone. Our zone cut detection needs improvement in general, and certainly in the case of DS records -- the parent name might not be the delegation point -- but that feels like a change unrelated to #2595. Let me know your thoughts. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-16 12:02:40 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/hickory-dns#3786
No description provided.