mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 19:25:56 +03:00
[GH-ISSUE #1983] Proposal: More generic server API #840
Labels
No labels
blocked
breaking-change
bug
bug:critical
bug:tests
cleanup
compliance
compliance
compliance
crate:all
crate:client
crate:native-tls
crate:proto
crate:recursor
crate:resolver
crate:resolver
crate:rustls
crate:server
crate:util
dependencies
docs
duplicate
easy
easy
enhance
enhance
enhance
feature:dns-over-https
feature:dns-over-quic
feature:dns-over-tls
feature:dnsssec
feature:global_lb
feature:mdns
feature:tsig
features:edns
has workaround
ops
perf
platform:WASM
platform:android
platform:fuchsia
platform:linux
platform:macos
platform:windows
pull-request
question
test
tools
tools
trust
unclear
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/hickory-dns#840
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @nmittler on GitHub (Jul 1, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1983
I have a very specific use case that is not supported well by the current server APIs. I've recently built a DNS Proxy for the Istio project. The proxy will run on each node in a Kubernetes cluster and all outbound DNS traffic from the pods running on the node will be redirected to it. The job of this proxy is to serve DNS records for "known" workloads within the service mesh (e.g.
my-service.my-ns.svc.cluster.local), and to forward everything else to the upstream resolver (e.g.kube-dns). DNS responses will indicateauthoritativeonly for "known" services that are served directly by the proxy.This doesn't fit into the current
Authoritymodel within the server, since theCatalogexpects that eachAuthorityis either authoritative for a particular domain or not. The set of domains for which the proxy is authoritative is potentially dynamic (e.g. a new cluster is added with a custom domain). For this reason, we want traffic for all domains to go through the proxy, and let it decide what to do. Architecturally, this boils down to is a chain of authorities rather than aCatalog.For my initial implementation, I had to ditch the
CatalogandAuthorityAPIs entirely and write a rawRequestHandlerfrom scratch. As a result, I ended up duplicating a significant portion of theCataloglogic, which seemed like a general failure of the API surface for this use case.Describe the solution you'd like
To better support the proxy use case described above, I suggest an API that is composable to allow chaining.
There are a couple of places where this problem could potentially be addressed:
RequestHandler: this is the top-level API. Unfortunately, you cannot chainRequestHandlers together because the trait methods use generics for theResponseHandlerargument. If we could makeRequestHandlerchainable, we could potentially turn theCatalogcode into a set of common utilities to make building newRequestHandlers easier. To take this even further, we could refactorCatalogto be a compositeRequestHandlerthat simply delegates to anotherRequestHandlerbased on the domain. This would effectively obviate the need for theAuthorityAPI entirely. IMO this is the cleanest solution architecturally.Authority: Alternatively, we could refactorCatalog/Authorityto allow for dynamically setting theauthoritativeflag on a per-request basis. This gets a little ugly because bothLookupandLookupErrorwould have to carry that information. There may be other limitations to theAuthorityAPI which would require similar changes, but I guess we would find that out as we go.Either of these would be somewhat destructive to our current API surface. To do this without breaking users, we might consider erecting a parallel set of APIs and deprecating the old ones (and eventually removing them entirely in a future release).
Anyway, those are my initial thoughts. I'm definitely open to other suggestions, given that I'm by no means an expert on the codebase.
Describe alternatives you've considered
NA
Additional context
NA
@nmittler commented on GitHub (Aug 2, 2023):
@bluejekyll @djc any thoughts?
@djc commented on GitHub (Aug 2, 2023):
Destroying the current API surface is not that big a deal IMO, as long as it becomes no less expressive.
Other than that I don't have strong feelings about your proposed ideas because I don't have a deep understanding of the proposed design. I do have the experience of building an authoritative name server which doesn't keep all of the authorities in memory (because that wouldn't scale), and so I've built a custom
RequestHandlerthat so far doesn't useCatalogorAuthorityat all. Instead it talks to Redis to figure out if it's authoritative for a given domain and fetches the necessary records from Redis as well. I wrote that over a year ago so I don't remember exactly why I ended up going that way, but IIRC the wholeCatalogandAuthoritymodel didn't really match the shape of the problem I was solving.I don't fully understand why the current API doesn't allow chaining of
RequestHandlers but I do think factoringCatalogandAuthorityinto building blocks that can more easily be used to buildRequestHandlersmakes sense at a high level.@bluejekyll commented on GitHub (Aug 2, 2023):
Yeah, I'm ok with this suggestion in principle. I did plan to add an authority for chaning things together, like a caching authority on top of the resolver or recursor. I can't remember what happened with that, probably sitting in an old branch. That being said, a question I have about your use case, specifically the need to change if something is authoritative or not. Off the top of my head, the authoritative flag I think most impacts negative responses, in the sense that if there are no records returned or NXDOMAIN, then the resolver can "know" that that is an authoritative response and stop searching. This doesn't seem to be the reason you're suggesting needing to change the authoritative flag. Would you mind explaining that in more detail? Does k8s use the authoritative flag for other things beyond that?
That being said, I have no issue with us making the API simpler in this area. It's an "old" interface at this point, and I haven't revisited it in a while, so I'm open to changes that will make some of these ideas you have simpler.
@nmittler commented on GitHub (Aug 4, 2023):
@djc if you ever get a few cycles, I'd be curious what you ended up doing. It might help to inform a new server API.
@djc commented on GitHub (Aug 8, 2023):
This is substantially all of my authoritative DNS server:
Let me know if you have questions, hope that helps!
@thedeadliestcatch commented on GitHub (Oct 4, 2024):
@djc Could you push the code to a repo (ready to build)? I'm trying to understand how to best fit a resolver (upstream), since my DNS server handler is only supposed to handle specific queries for testing. The redis parts and unresolved imports make it a tad confusing, even if the snippet already resolved quite a few questions for me (thank you for that!).
Any other upstream resolver examples would be fantastic, alas it seems hickory_server comes with none (unless you want to grok the complete server code).
@marcus0x62 commented on GitHub (Oct 29, 2025):
This was implemented in #2161