[PR #2325] [MERGED] Improve recursor logic by eliminating redundant NS requests and adding recursor support for NS referrals. #2953

Closed
opened 2026-03-16 11:17:08 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/hickory-dns/hickory-dns/pull/2325
Author: @marcus0x62
Created: 7/25/2024
Status: Merged
Merged: 7/28/2024
Merged by: @bluejekyll

Base: mainHead: recursor_logic


📝 Commits (4)

  • 78d5776 Improve recursor logic by eliminating redundant NS requests and adding recursor support for NS referrals.
  • 88d4fbb Reintroduce changeset; see comment in previous commit.
  • 8b63f77 Change the zone name handling logic to account for NS queries with the DO bit set - in that case we
  • 67077c9 Merge branch 'main' into recursor_logic

📊 Changes

6 files changed (+328 additions, -29 deletions)

View changed files

📝 crates/proto/src/error.rs (+46 -0)
📝 crates/recursor/src/error.rs (+17 -5)
📝 crates/recursor/src/recursor_dns_handle.rs (+253 -23)
📝 crates/resolver/src/caching_client.rs (+5 -0)
📝 crates/resolver/src/dns_lru.rs (+4 -0)
📝 crates/resolver/src/name_server/name_server_pool.rs (+3 -1)

📄 Description

Improve recursor logic by:

  1. Eliminating redundant NS requests when querying a record with a host component (i.e., host.example.com) by using the parent zone of the record being queried in ns_pool_for_zone.

The current resolver logic will send an NS query for every element of a queried name, which for most cases, results in an extra NS query being sent for the hostname portion of the domain. For instance, assuming a cold start/empty cache, host.example.com results in the following queries:

 query NS com. via . -> com. name servers + glue
 query NS example.com. via com. -> example.com. name servers + glue
 query NS host.example.com. via example.com. -> typically a SOA pointing back to the same NS
 query A host.example.com via example.com -> authoritative answer

By changing the logic to start the ns_pool_for_zone search on the parent zone name, the superfluous NS request is eliminated, and the queries sent for the example above now look like this:

 query NS com. via . -> com. name servers + glue
 query NS example.com. via com. -> example.com. name servers + glue
 query A host.example.com via example.com -> authoritative answer

In the case where a query is made for a second-level domain, an A query will be sent to the top-level domain name servers, but there still will not be any redundant queries due to the second change in this PR, which is to create a new recursor error variant (ForwardNS) to reflect when a referral to a different set of nameservers is encountered.

  1. The recursor::Error::ForwardNS error variant allows the recursor to continue resolution when an authoritative server returns no authoritative answers but does return a set of authoritative name servers (and, possibly, glue records) to further resolve the query. There is also a new function in crates/recursor/src/recursor_dns_handle.rs (ns_pool_for_referral) to build a new NS Pool based on this referral information and error handling logic in in the resolve function to trigger the referral logic.

To continue the previous example, a request sent for A example.com will result in the following queries (again, cold-start, no cache assumed:)

 query NS com. via . -> com. name servers + glue
 query A example.com. via com. -> example.com. name servers + glue
 query A example.com via example.com -> authoritative answer

After the first query, ns_pool_for_zone is done - it uses the zone 'com.' to try to resolve
'example.com.'. The root servers for com. do not contain the zone data for example.com., but are authoritative for the example.com NS delegation records, and return those. Since the response contains no answer but does include NS records, the Error::ForwardNS condition is the result of the second lookup, which triggers a call to build_pool_for_referral and a new query for A example.com via the correct servers.


🔄 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/2325 **Author:** [@marcus0x62](https://github.com/marcus0x62) **Created:** 7/25/2024 **Status:** ✅ Merged **Merged:** 7/28/2024 **Merged by:** [@bluejekyll](https://github.com/bluejekyll) **Base:** `main` ← **Head:** `recursor_logic` --- ### 📝 Commits (4) - [`78d5776`](https://github.com/hickory-dns/hickory-dns/commit/78d5776c7430665a5e58935c68182c2533e0b5b5) Improve recursor logic by eliminating redundant NS requests and adding recursor support for NS referrals. - [`88d4fbb`](https://github.com/hickory-dns/hickory-dns/commit/88d4fbb28ab8d1679eb4db31286d3e091053c489) Reintroduce changeset; see comment in previous commit. - [`8b63f77`](https://github.com/hickory-dns/hickory-dns/commit/8b63f7707a0ccfe60cab3eb88ee35c240b068312) Change the zone name handling logic to account for NS queries with the DO bit set - in that case we - [`67077c9`](https://github.com/hickory-dns/hickory-dns/commit/67077c9d7253218a49f2fc6c2fc6ae94d8f8c113) Merge branch 'main' into recursor_logic ### 📊 Changes **6 files changed** (+328 additions, -29 deletions) <details> <summary>View changed files</summary> 📝 `crates/proto/src/error.rs` (+46 -0) 📝 `crates/recursor/src/error.rs` (+17 -5) 📝 `crates/recursor/src/recursor_dns_handle.rs` (+253 -23) 📝 `crates/resolver/src/caching_client.rs` (+5 -0) 📝 `crates/resolver/src/dns_lru.rs` (+4 -0) 📝 `crates/resolver/src/name_server/name_server_pool.rs` (+3 -1) </details> ### 📄 Description Improve recursor logic by: 1) Eliminating redundant NS requests when querying a record with a host component (i.e., host.example.com) by using the parent zone of the record being queried in ns_pool_for_zone. The current resolver logic will send an NS query for every element of a queried name, which for most cases, results in an extra NS query being sent for the hostname portion of the domain. For instance, assuming a cold start/empty cache, host.example.com results in the following queries: query NS com. via . -> com. name servers + glue query NS example.com. via com. -> example.com. name servers + glue query NS host.example.com. via example.com. -> typically a SOA pointing back to the same NS query A host.example.com via example.com -> authoritative answer By changing the logic to start the ns_pool_for_zone search on the parent zone name, the superfluous NS request is eliminated, and the queries sent for the example above now look like this: query NS com. via . -> com. name servers + glue query NS example.com. via com. -> example.com. name servers + glue query A host.example.com via example.com -> authoritative answer In the case where a query is made for a second-level domain, an A query will be sent to the top-level domain name servers, but there still will not be any redundant queries due to the second change in this PR, which is to create a new recursor error variant (ForwardNS) to reflect when a referral to a different set of nameservers is encountered. 2) The recursor::Error::ForwardNS error variant allows the recursor to continue resolution when an authoritative server returns no authoritative answers but does return a set of authoritative name servers (and, possibly, glue records) to further resolve the query. There is also a new function in crates/recursor/src/recursor_dns_handle.rs (ns_pool_for_referral) to build a new NS Pool based on this referral information and error handling logic in in the resolve function to trigger the referral logic. To continue the previous example, a request sent for A example.com will result in the following queries (again, cold-start, no cache assumed:) query NS com. via . -> com. name servers + glue query A example.com. via com. -> example.com. name servers + glue query A example.com via example.com -> authoritative answer After the first query, ns_pool_for_zone is done - it uses the zone 'com.' to try to resolve 'example.com.'. The root servers for com. do not contain the zone data for example.com., but are authoritative for the example.com NS delegation records, and return those. Since the response contains no answer but does include NS records, the Error::ForwardNS condition is the result of the second lookup, which triggers a call to build_pool_for_referral and a new query for A example.com via the correct servers. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-03-16 11:17:08 +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#2953
No description provided.