[GH-ISSUE #1100] DNS lookup on custom TCP-like stream? #606

Open
opened 2026-03-15 23:25:26 +03:00 by kerem · 11 comments
Owner

Originally created by @Mygod on GitHub (May 10, 2020).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1100

What is the best way to implement DNS lookup on a custom struct that implements DnsStreamHandle, e.g. wrapping a tokio::net::UnixStream or a proxy TCP stream, so that it can use all the features in this library, e.g. connection reuse?

Originally created by @Mygod on GitHub (May 10, 2020). Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/1100 What is the best way to implement DNS lookup on a custom struct that implements `DnsStreamHandle`, e.g. wrapping a `tokio::net::UnixStream` or a proxy TCP stream, so that it can use all the features in this library, e.g. connection reuse?
Author
Owner

@bluejekyll commented on GitHub (May 10, 2020):

Which part of the library do you mean? The trust-dns-resolver library already does this, you can just configure the resolver to only use TCP/TLS/HTTPS, and then it would reuse those connections.

If you want to get a raw packet, then trust-dns-client is probably what you want, though that won't do anything like CNAME resolution, and you'll need to interpret the DNS Message to extract the data types you want.

<!-- gh-comment-id:626376286 --> @bluejekyll commented on GitHub (May 10, 2020): Which part of the library do you mean? The `trust-dns-resolver` library already does this, you can just configure the resolver to only use TCP/TLS/HTTPS, and then it would reuse those connections. If you want to get a raw packet, then `trust-dns-client` is probably what you want, though that won't do anything like CNAME resolution, and you'll need to interpret the DNS Message to extract the data types you want.
Author
Owner

@Mygod commented on GitHub (May 10, 2020):

Ah there is a client library. I missed that.

Though my use case is slightly different. TcpClientStream is still restrictive for us, in particular, the async fn in trust_dns_proto::tcp::Connect only takes SocketAddr, however, we want the stream initialization to be done via some other process (UnixStream or proxy set up). We currently have re-implemented a lot of stuff but it would be great if we can use the connection pooling in this library...

<!-- gh-comment-id:626378729 --> @Mygod commented on GitHub (May 10, 2020): Ah there is a client library. I missed that. Though my use case is slightly different. `TcpClientStream` is still restrictive for us, in particular, the `async fn` in `trust_dns_proto::tcp::Connect` only takes `SocketAddr`, however, we want the stream initialization to be done via some other process (`UnixStream` or proxy set up). We currently have re-implemented [a lot of stuff](https://github.com/shadowsocks/shadowsocks-rust/blob/1a219d32d22af7ab2db2a0dcddfa6497108612af/src/relay/dnsrelay/upstream.rs#L86) but it would be great if we can use the connection pooling in this library...
Author
Owner

@bluejekyll commented on GitHub (May 10, 2020):

I think I understand what you want, though I don't think the library is necessarily in the best state to make that easy. I think you could implement your own version of TcpClientStream and then you could use the https://docs.rs/trust-dns-client/0.19.5/trust_dns_client/client/struct.AsyncClient.html#method.connect for using it.

You may want to explore using https://docs.rs/trust-dns-proto/0.19.5/trust_dns_proto/xfer/dns_multiplexer/struct.DnsMultiplexer.html for multiplexing over a single TCP stream. Then there is the https://docs.rs/trust-dns-proto/0.19.5/trust_dns_proto/xfer/struct.DnsExchange.html which can be used to wrap a multiplexed stream and properly dispatch and convert responses back to the requesting task. While the Client itself is not used in the trust-dns-resolver, the exchange and multiplexer are.

<!-- gh-comment-id:626380655 --> @bluejekyll commented on GitHub (May 10, 2020): I think I understand what you want, though I don't think the library is necessarily in the best state to make that easy. I think you could implement your own version of `TcpClientStream` and then you could use the https://docs.rs/trust-dns-client/0.19.5/trust_dns_client/client/struct.AsyncClient.html#method.connect for using it. You may want to explore using https://docs.rs/trust-dns-proto/0.19.5/trust_dns_proto/xfer/dns_multiplexer/struct.DnsMultiplexer.html for multiplexing over a single TCP stream. Then there is the https://docs.rs/trust-dns-proto/0.19.5/trust_dns_proto/xfer/struct.DnsExchange.html which can be used to wrap a multiplexed stream and properly dispatch and convert responses back to the requesting task. While the Client itself is not used in the trust-dns-resolver, the exchange and multiplexer are.
Author
Owner

@Mygod commented on GitHub (May 10, 2020):

Thanks! By the way does this library support connection pooling?

<!-- gh-comment-id:626383063 --> @Mygod commented on GitHub (May 10, 2020): Thanks! By the way does this library support connection pooling?
Author
Owner

@bluejekyll commented on GitHub (May 11, 2020):

The Client doesn’t, but the Resolver does.

<!-- gh-comment-id:626445447 --> @bluejekyll commented on GitHub (May 11, 2020): The Client doesn’t, but the Resolver does.
Author
Owner

@Mygod commented on GitHub (May 11, 2020):

Ah I have given up trying to integrate the client library. For now I think I will keep implementing our own client/server code along with trust-dns-proto...

I'd be keen to go back if it gets easier for me to integrate the client library. 🤣

<!-- gh-comment-id:626446496 --> @Mygod commented on GitHub (May 11, 2020): Ah I have given up trying to integrate the client library. For now I think I will keep implementing our own client/server code along with `trust-dns-proto`... I'd be keen to go back if it gets easier for me to integrate the client library. :rofl:
Author
Owner

@bluejekyll commented on GitHub (May 11, 2020):

Btw, it is possible in the Resolver to use custom TCP streams, by way of implementing a custom Runtime and or ConnectionProvider

<!-- gh-comment-id:626860531 --> @bluejekyll commented on GitHub (May 11, 2020): Btw, it is possible in the Resolver to use custom TCP streams, by way of implementing a custom `Runtime` and or `ConnectionProvider`
Author
Owner

@bluejekyll commented on GitHub (May 11, 2020):

Also, if you have notes on what was complicated, and what you would like to see changed in the Client, we should capture those, and maybe someone will have some energy to work on them.

<!-- gh-comment-id:626861045 --> @bluejekyll commented on GitHub (May 11, 2020): Also, if you have notes on what was complicated, and what you would like to see changed in the Client, we should capture those, and maybe someone will have some energy to work on them.
Author
Owner

@Mygod commented on GitHub (May 12, 2020):

Yes I made a preliminary attempt here. How do I integrate it with trust-dns so that I can use the connection pool etc?

<!-- gh-comment-id:627036424 --> @Mygod commented on GitHub (May 12, 2020): Yes I made a preliminary attempt [here](https://gist.github.com/Mygod/2532e73063986635ce1f43db4e5825dd). How do I integrate it with trust-dns so that I can use the connection pool etc?
Author
Owner

@Jason5Lee commented on GitHub (Sep 1, 2020):

I have a similar requirement where I want to resolve DNS through socks5 proxy.

<!-- gh-comment-id:684895216 --> @Jason5Lee commented on GitHub (Sep 1, 2020): I have a similar requirement where I want to resolve DNS through socks5 proxy.
Author
Owner

@kmod-midori commented on GitHub (Nov 17, 2020):

Most libraries dealing with streams accept something like where S: AsyncRead + AsyncWrite + Unpin, making them more flexible. I wonder if we could have something similar, like a trait StreamFactory?

<!-- gh-comment-id:729053787 --> @kmod-midori commented on GitHub (Nov 17, 2020): Most libraries dealing with streams accept something like `where S: AsyncRead + AsyncWrite + Unpin`, making them more flexible. I wonder if we could have something similar, like a `trait StreamFactory`?
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#606
No description provided.