[GH-ISSUE #1800] Specify IP address of upstream servers directly? #770

Closed
opened 2026-03-16 00:11:20 +03:00 by kerem · 6 comments
Owner

Originally created by @phylake on GitHub (Oct 14, 2022).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1800

I looked at pub struct ResolverOpts and did a couple queries in GitHub issues but didn't find anything

I'm wondering: is there an equivalent of dnsmasq's --server option? If not can you point me to where I'd hook into the DNS request and provide a different response?

Originally created by @phylake on GitHub (Oct 14, 2022). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1800 I looked at `pub struct ResolverOpts` and did a couple queries in GitHub issues but didn't find anything I'm wondering: is there an equivalent of dnsmasq's [`--server` option](https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html)? If not can you point me to where I'd hook into the DNS request and provide a different response?
kerem 2026-03-16 00:11:20 +03:00
  • closed this issue
  • added the
    question
    label
Author
Owner

@bluejekyll commented on GitHub (Oct 14, 2022):

I think you're looking for ResolverConfig specifically either configure everything all at once: https://docs.rs/trust-dns-resolver/0.22.0/trust_dns_resolver/config/struct.ResolverConfig.html#method.from_parts or add each name server in one at a time: https://docs.rs/trust-dns-resolver/0.22.0/trust_dns_resolver/config/struct.ResolverConfig.html#method.add_name_server

<!-- gh-comment-id:1279558963 --> @bluejekyll commented on GitHub (Oct 14, 2022): I think you're looking for `ResolverConfig` specifically either configure everything all at once: https://docs.rs/trust-dns-resolver/0.22.0/trust_dns_resolver/config/struct.ResolverConfig.html#method.from_parts or add each name server in one at a time: https://docs.rs/trust-dns-resolver/0.22.0/trust_dns_resolver/config/struct.ResolverConfig.html#method.add_name_server
Author
Owner

@phylake commented on GitHub (Oct 17, 2022):

Looking at what add_name_server does I don't think this is what I'm looking for

pub fn add_name_server(&mut self, name_server: NameServerConfig) {
        self.name_servers.push(name_server);
}

I'm looking to provide a name server for a FQDN. The use case here is that on a Kubernetes cluster I know that CoreDNS running on the cluster is authoritative for *.cluster.local. so I don't want the query to be forwarded to any other name server

<!-- gh-comment-id:1281087338 --> @phylake commented on GitHub (Oct 17, 2022): Looking at what `add_name_server` does I don't think this is what I'm looking for ```rust pub fn add_name_server(&mut self, name_server: NameServerConfig) { self.name_servers.push(name_server); } ``` I'm looking to provide a name server for a FQDN. The use case here is that on a Kubernetes cluster I know that CoreDNS running on the cluster is authoritative for `*.cluster.local.` so I don't want the query to be forwarded to any other name server
Author
Owner

@phylake commented on GitHub (Oct 18, 2022):

I started looking at how to do this. Looks like with my own impl RequestHandler I can spin up a resolver and get back a Lookup. Not sure how to convert that to a MessageResponse though. Am I on the right track at least @bluejekyll? I'm currently staring at https://docs.rs/trust-dns-server/0.22.0/trust_dns_server/authority/struct.MessageResponseBuilder.html#method.build wondering what to give it

At a high level I'm trying to build a DNS server that mostly forward DNS requests onto a public DNS server and conditionally forwards to an authoritative DNS server I run

<!-- gh-comment-id:1283074486 --> @phylake commented on GitHub (Oct 18, 2022): I started looking at how to do this. Looks like with my own `impl RequestHandler` I can spin up a resolver and get back a `Lookup`. Not sure how to convert that to a `MessageResponse` though. Am I on the right track at least @bluejekyll? I'm currently staring at https://docs.rs/trust-dns-server/0.22.0/trust_dns_server/authority/struct.MessageResponseBuilder.html#method.build wondering what to give it At a high level I'm trying to build a DNS server that mostly forward DNS requests onto a public DNS server and conditionally forwards to an authoritative DNS server I run
Author
Owner

@bluejekyll commented on GitHub (Oct 18, 2022):

Ah, I think I misunderstood the context of what you were trying to do. I understand better now. I think what I would do is build a new Authority that has a list of other Authorities associated to it, and then in the message processing you could inspect the request and then decide to forward on based on that inspection. Does that help? or do you think you need more details?

The Forwarding Authority is probably the best example to use for this: https://github.com/bluejekyll/trust-dns/blob/main/crates/server/src/store/forwarder/authority.rs#L95

<!-- gh-comment-id:1283096006 --> @bluejekyll commented on GitHub (Oct 18, 2022): Ah, I think I misunderstood the context of what you were trying to do. I understand better now. I think what I would do is build a new Authority that has a list of other Authorities associated to it, and then in the message processing you could inspect the request and then decide to forward on based on that inspection. Does that help? or do you think you need more details? The Forwarding Authority is probably the best example to use for this: https://github.com/bluejekyll/trust-dns/blob/main/crates/server/src/store/forwarder/authority.rs#L95
Author
Owner

@phylake commented on GitHub (Oct 20, 2022):

I think I need more details. This conditional logic I'm talking about is also dynamic in nature based on what FQDNs are present and there is additional filtering logic I'd like to add. In the simple forwarding case what's the fastest path given a pub struct Lookup from lookup() and turn it (or its fields) into a pub struct MessageResponse to give send_response()?

Tell me if I'm going about this all wrong. Still looking through the source (which is super clean, btw 💯) and this is where I'm at

<!-- gh-comment-id:1286136841 --> @phylake commented on GitHub (Oct 20, 2022): I think I need more details. This conditional logic I'm talking about is also dynamic in nature based on what FQDNs are present and there is additional filtering logic I'd like to add. In the simple forwarding case what's the fastest path given a `pub struct Lookup` from [`lookup()`](https://docs.rs/trust-dns-resolver/0.22.0/trust_dns_resolver/struct.Resolver.html#method.lookup) and turn it (or its fields) into a `pub struct MessageResponse` to give [`send_response()`](https://docs.rs/trust-dns-server/0.22.0/trust_dns_server/server/struct.ResponseHandle.html#method.send_response)? Tell me if I'm going about this all wrong. Still looking through the source (which is super clean, btw 💯) and this is where I'm at
Author
Owner

@phylake commented on GitHub (Oct 20, 2022):

I think I got it. How does this look for the simple forwarding case? I'm new to rust just FYI

#[async_trait::async_trait]
impl RequestHandler for RequestHandlerImpl {
    async fn handle_request<R: ResponseHandler>(
        &self,
        request: &Request,
        mut response_handle: R,
    ) -> ResponseInfo {

        let result = match request.message_type() {
            MessageType::Query => match request.op_code() {
                OpCode::Query => {
                    let host = format!("{}", request.request_info().query.name());
                    println!("query received: {}", host);
                    let lookup = self.resolver.lookup_ip(host).await.unwrap();
                    let builder = MessageResponseBuilder::from_message_request(request);
                    let response = builder.build(
                        *request.header(),
                        lookup.as_lookup().record_iter(),
                        vec![],
                        vec![],
                        vec![],
                    );
                    response_handle.send_response(response).await
                }
<!-- gh-comment-id:1286201376 --> @phylake commented on GitHub (Oct 20, 2022): I think I got it. How does this look for the simple forwarding case? I'm new to rust just FYI ```rust #[async_trait::async_trait] impl RequestHandler for RequestHandlerImpl { async fn handle_request<R: ResponseHandler>( &self, request: &Request, mut response_handle: R, ) -> ResponseInfo { let result = match request.message_type() { MessageType::Query => match request.op_code() { OpCode::Query => { let host = format!("{}", request.request_info().query.name()); println!("query received: {}", host); let lookup = self.resolver.lookup_ip(host).await.unwrap(); let builder = MessageResponseBuilder::from_message_request(request); let response = builder.build( *request.header(), lookup.as_lookup().record_iter(), vec![], vec![], vec![], ); response_handle.send_response(response).await } ```
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#770
No description provided.