[GH-ISSUE #2079] Lookup to MessageResponse? #875

Open
opened 2026-03-16 00:43:17 +03:00 by kerem · 11 comments
Owner

Originally created by @phylake on GitHub (Oct 25, 2023).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2079

Using the resolver I get back a struct Lookup but it's unclear how to transform that into a MessageResponse given this function signature

pub fn build<'a, A, N, S, D>(
        self,
        header: Header,
        answers: A,
        name_servers: N,
        soa: S,
        additionals: D,
    ) -> MessageResponse<'q, 'a, A::IntoIter, N::IntoIter, S::IntoIter, D::IntoIter>

The Lookup has a flat [Record]. I know I could filter out the SOAs pretty easily but I'm not sure what to do about the Additionals.

Should I be using the client crate instead of the resolver, perhaps? Nothing is standing out on AsyncClient that would help me.

Originally created by @phylake on GitHub (Oct 25, 2023). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/2079 Using the resolver I get back a `struct Lookup` but it's unclear how to transform that into a `MessageResponse` given this function signature ``` pub fn build<'a, A, N, S, D>( self, header: Header, answers: A, name_servers: N, soa: S, additionals: D, ) -> MessageResponse<'q, 'a, A::IntoIter, N::IntoIter, S::IntoIter, D::IntoIter> ``` The `Lookup` has a flat `[Record]`. I know I could filter out the SOAs pretty easily but I'm not sure what to do about the Additionals. Should I be using the client crate instead of the resolver, perhaps? Nothing is standing out on `AsyncClient` that would help me.
Author
Owner

@djc commented on GitHub (Oct 26, 2023):

What's your use case, why do you want to get a MessageResponse out of a resolver Lookup?

<!-- gh-comment-id:1780885733 --> @djc commented on GitHub (Oct 26, 2023): What's your use case, why do you want to get a `MessageResponse` out of a resolver `Lookup`?
Author
Owner

@phylake commented on GitHub (Oct 26, 2023):

Really any use case where I need to perform a request on behalf of the client and return it. One is querying different DNS servers depending on the host being requested. Others are modifying the question being asked or the answer being given.

<!-- gh-comment-id:1781520824 --> @phylake commented on GitHub (Oct 26, 2023): Really any use case where I need to perform a request on behalf of the client and return it. One is querying different DNS servers depending on the host being requested. Others are modifying the question being asked or the answer being given.
Author
Owner

@djc commented on GitHub (Oct 26, 2023):

That doesn't sound like the resolver interface is for you.

<!-- gh-comment-id:1781592901 --> @djc commented on GitHub (Oct 26, 2023): That doesn't sound like the resolver interface is for you.
Author
Owner

@bluejekyll commented on GitHub (Oct 28, 2023):

Yeah, I'm not totally clear what you are trying to do. We do use the resolver internally in the server for "forwarding" requests to upstream resolvers, that has some logic for mapping the lookup result into a Message that you could look at:

github.com/hickory-dns/hickory-dns@b0c0566483/crates/server/src/store/forwarder/authority.rs (L166C1-L173)

There's not a lot of logic there, and it only uses the primary record results. It might help to clarify that the Resolver is not a simple DNS client, it collapses CNAME chains and does additional lookups in order to resolve the query to ideally find the best result for the query. If you want a more direct client request, then you should look at the Client crate/library, though that is a more complex and low level interface.

<!-- gh-comment-id:1783897108 --> @bluejekyll commented on GitHub (Oct 28, 2023): Yeah, I'm not totally clear what you are trying to do. We do use the resolver internally in the server for "forwarding" requests to upstream resolvers, that has some logic for mapping the lookup result into a Message that you could look at: https://github.com/hickory-dns/hickory-dns/blob/b0c05664837684d74d396dae8cceb6171ea4c556/crates/server/src/store/forwarder/authority.rs#L166C1-L173 There's not a lot of logic there, and it only uses the primary record results. It might help to clarify that the Resolver is not a simple DNS client, it collapses CNAME chains and does additional lookups in order to resolve the query to ideally find the best result for the query. If you want a more direct client request, then you should look at the Client crate/library, though that is a more complex and low level interface.
Author
Owner

@phylake commented on GitHub (Oct 30, 2023):

it collapses CNAME chains and does additional lookups in order to resolve the query to ideally find the best result for the query

That's great I want all of that functionality.

I'm not totally clear what you are trying to do

I guess some more context is needed. One concrete example is split horizon DNS. I have a

impl RequestHandler for MyProject {
    async fn handle_request<R: ResponseHandler>(
        &self,
        request: &Request,
        mut response_handle: R,
    ) -> ResponseInfo
}

My struct MyProject has a TokioAsyncResolver I use to resolve the host (request.request_info().query.name()) requested. Conditionally, I alter the host (i.e., the question) being requested and return not the answer to the question asked, but the answer to the question I asked. All of this works great, btw. At this point I don't have anything to put in the soa or additionals of the MessageResponseBuilder build function

pub fn build<'a, A, N, S, D>(
        self,
        header: Header,
        answers: A,
        name_servers: N,
        soa: S,
        additionals: D,
    ) -> MessageResponse<'q, 'a, A::IntoIter, N::IntoIter, S::IntoIter, D::IntoIter>

so the reason for opening this issue was really around correctness. The resolver doesn't give me soa or additional back in the Lookup

<!-- gh-comment-id:1785868219 --> @phylake commented on GitHub (Oct 30, 2023): > it collapses CNAME chains and does additional lookups in order to resolve the query to ideally find the best result for the query That's great I want all of that functionality. > I'm not totally clear what you are trying to do I guess some more context is needed. One concrete example is split horizon DNS. I have a ```rust impl RequestHandler for MyProject { async fn handle_request<R: ResponseHandler>( &self, request: &Request, mut response_handle: R, ) -> ResponseInfo } ``` My `struct MyProject` has a `TokioAsyncResolver` I use to resolve the host (`request.request_info().query.name()`) requested. Conditionally, I alter the host (i.e., the question) being requested and return not the answer to the question asked, but the answer to the question I asked. All of this works great, btw. At this point I don't have anything to put in the `soa` or `additionals` of the `MessageResponseBuilder` build function ```rust pub fn build<'a, A, N, S, D>( self, header: Header, answers: A, name_servers: N, soa: S, additionals: D, ) -> MessageResponse<'q, 'a, A::IntoIter, N::IntoIter, S::IntoIter, D::IntoIter> ``` so the reason for opening this issue was really around **correctness**. The resolver doesn't give me `soa` or `additional` back in the `Lookup`
Author
Owner

@balboah commented on GitHub (Jun 28, 2024):

I'm also curious on how to retrieve the additionals section from a Lookup result?

<!-- gh-comment-id:2196579230 --> @balboah commented on GitHub (Jun 28, 2024): I'm also curious on how to retrieve the additionals section from a `Lookup` result?
Author
Owner

@djc commented on GitHub (Jun 28, 2024):

@balboah what are you trying to achieve? What's the use case?

<!-- gh-comment-id:2196586978 --> @djc commented on GitHub (Jun 28, 2024): @balboah what are you trying to achieve? What's the use case?
Author
Owner

@balboah commented on GitHub (Jun 28, 2024):

To resolve dns records of all kinds from 3rd party upstream dns servers on behalf of clients, while not using hickory as a server

<!-- gh-comment-id:2196697311 --> @balboah commented on GitHub (Jun 28, 2024): To resolve dns records of all kinds from 3rd party upstream dns servers on behalf of clients, while not using hickory as a server
Author
Owner

@djc commented on GitHub (Jun 28, 2024):

Why don't you want to use hickory as a server?

<!-- gh-comment-id:2196709786 --> @djc commented on GitHub (Jun 28, 2024): Why don't you want to use hickory as a server?
Author
Owner

@balboah commented on GitHub (Jun 28, 2024):

Because of other preferences and requirements. Not sure why this matters? 🙂

There's a resolver for resolving queries of all types, I would expect it to also be able to resolve the additional section? Although the clients can probably live without this

<!-- gh-comment-id:2196766722 --> @balboah commented on GitHub (Jun 28, 2024): Because of other preferences and requirements. Not sure why this matters? 🙂 There's a resolver for resolving queries of all types, I would expect it to also be able to resolve the additional section? Although the clients can probably live without this
Author
Owner

@djc commented on GitHub (Jun 28, 2024):

Because of other preferences and requirements. Not sure why this matters? 🙂

I always like to understand requirements that our users have to take them into account for future plans.

There's a resolver for resolving queries of all types, I would expect it to also be able to resolve the additional section? Although the clients can probably live without this

I think the conceptual mismatch here is that a Lookup potentially represents a stream of DNS response messages, so that there's not one additionals section to cleanly represent. As such, there is not currently a straightforward way to do this. I think there's some tension here between a desire for interpretation (as alluded to in earlier comments around collapsing CNAME chains and doing extra lookups) from the resolver crate versus acting as a "simple" proxy for which the client crate might be a better fit.

<!-- gh-comment-id:2196925895 --> @djc commented on GitHub (Jun 28, 2024): > Because of other preferences and requirements. Not sure why this matters? 🙂 I always like to understand requirements that our users have to take them into account for future plans. > There's a resolver for resolving queries of all types, I would expect it to also be able to resolve the additional section? Although the clients can probably live without this I think the conceptual mismatch here is that a `Lookup` potentially represents a stream of DNS response messages, so that there's not one additionals section to cleanly represent. As such, there is not currently a straightforward way to do this. I think there's some tension here between a desire for interpretation (as alluded to in earlier comments around collapsing CNAME chains and doing extra lookups) from the resolver crate versus acting as a "simple" proxy for which the client crate might be a better fit.
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#875
No description provided.