mirror of
https://github.com/hickory-dns/hickory-dns.git
synced 2026-04-25 19:25:56 +03:00
[GH-ISSUE #736] How to send DNS queries in parallel via UDP? #287
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#287
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 @ovidiu-ionescu on GitHub (Apr 7, 2019).
Original GitHub issue: https://github.com/hickory-dns/hickory-dns/issues/736
I tried to expand on the async DNS query example but the wait time seems to increase linearly with the amount of DNS queries. I get the impression the system is waiting for the first request to get a reply before issuing the second request and so on.
Please provide an example where a number of UDP DNS requests are being submitted without waiting for the server to respond in between.
@bluejekyll commented on GitHub (Apr 8, 2019):
This shouldn’t be the case. Could you share your code?
@ovidiu-ionescu commented on GitHub (Apr 8, 2019):
Here's my code:
github.com/ovidiu-ionescu/learning-rust@fc8514355f/src/dns_resolver.rsI just took the async example from trust-dns and added a for loop to it.
@bluejekyll commented on GitHub (Apr 8, 2019):
I won’t have time to provide a full example for a little bit, but your second loop is serializing the futures, what you want is to throw your collection into a select, specifically,
select_all: https://docs.rs/futures/0.1.26/futures/future/fn.select_all.html@ovidiu-ionescu commented on GitHub (Apr 8, 2019):
I don't mind waiting for all of them to finish before proceeding, trouble is that one request takes about 20 milliseconds and five take a bit more than 100. I suspect most of that time is actually taken by the packets traveling to Google's DNS and back. I was hoping to get a shorter time overall by sending all the requests at once so that they all travel together and hopefully all five only take a little bit more than just one.
@bluejekyll commented on GitHub (Apr 8, 2019):
In that case, look at https://docs.rs/futures/0.1.26/futures/future/fn.join_all.html, that will combine all the futures and execute them all in parallel. I think it will work better than your loop. You could also configure the resolver to only use tcp, which might provide more reliable performance?
@bluejekyll commented on GitHub (Apr 8, 2019):
It might be good to make sure we're both on the same page in our understanding of futures in Rust. Futures are lazy, this means they shouldn't start executing before being polled. The futures you're creating should not actually even submit the query until you poll them, that would be the
block_oncall in your code. I used to have some bugs in this area, it can be a subtle mistake, I think they're all cleaned up at this point. The reason thejoin_allI mention above would be better than your loop, is that each of those futures you've created for the query, won't actually start until theblock_on, which means each is serial and waiting for the previous to execute. With ajoin_all, all the futures will be started and then waited on if that is the thing you are putting into theblock_on.That should fix your issue.
@bluejekyll commented on GitHub (Apr 8, 2019):
Also, if you want a recursive stub resolver for queries, I would recommend using the resolver: https://docs.rs/trust-dns-resolver/0.11.0-alpha.3/trust_dns_resolver/
It will handle things like CNAME chain resolutions and managing upgrades from UDP to TCP connections on truncation, etc...
@ovidiu-ionescu commented on GitHub (Apr 8, 2019):
join_alldid make a difference, I see much better times.I also learned that futures are lazy.
A double thank you!
The improved version of the code, using
join_all:github.com/ovidiu-ionescu/learning-rust@70d4db1110/src/dns_resolver.rs