1use std::fmt;
2use std::future::Future;
3use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
4use std::pin::Pin;
5use std::sync::Arc;
6use std::task::{Context, Poll};
7
8use crate::error::Error;
9use crate::host::HostResults;
10use crate::nameinfo::NameInfoResult;
11use crate::resolver::{Options, Resolver};
12
13#[cfg(cares1_29)]
14use c_ares::ServerStateFlags;
15
16#[must_use]
18pub struct CAresFuture<T> {
19 inner: futures_channel::oneshot::Receiver<c_ares::Result<T>>,
20 _resolver: Arc<Resolver>,
21}
22
23impl<T> fmt::Debug for CAresFuture<T> {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 f.debug_struct("CAresFuture").finish_non_exhaustive()
26 }
27}
28
29impl<T> CAresFuture<T> {
30 fn new(
31 promise: futures_channel::oneshot::Receiver<c_ares::Result<T>>,
32 resolver: Arc<Resolver>,
33 ) -> Self {
34 Self {
35 inner: promise,
36 _resolver: resolver,
37 }
38 }
39
40 fn pin_get_inner(
41 self: Pin<&mut Self>,
42 ) -> Pin<&mut futures_channel::oneshot::Receiver<c_ares::Result<T>>> {
43 unsafe { self.map_unchecked_mut(|s| &mut s.inner) }
44 }
45}
46
47impl<T> Future for CAresFuture<T> {
48 type Output = c_ares::Result<T>;
49
50 fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
51 self.pin_get_inner()
52 .poll(cx)
53 .map(|result| result.unwrap_or(Err(c_ares::Error::ECANCELLED)))
54 }
55}
56
57pub struct FutureResolver {
69 inner: Arc<Resolver>,
70}
71
72impl fmt::Debug for FutureResolver {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 f.debug_struct("FutureResolver").finish_non_exhaustive()
75 }
76}
77
78macro_rules! futurize {
81 ($resolver:expr, $query:ident, $($arg:expr),+ $(,)?) => {{
82 let (sender, receiver) = futures_channel::oneshot::channel();
83 $resolver.$query($($arg,)+ |result| {
84 let _ = sender.send(result);
85 });
86 let resolver = Arc::clone(&$resolver);
87 CAresFuture::new(receiver, resolver)
88 }};
89}
90
91impl FutureResolver {
92 pub fn new() -> Result<Self, Error> {
102 let options = Options::default();
103 Self::with_options(options)
104 }
105
106 pub fn with_options(options: Options) -> Result<Self, Error> {
108 let inner = Resolver::with_options(options)?;
109 let resolver = Self {
110 inner: Arc::new(inner),
111 };
112 Ok(resolver)
113 }
114
115 #[cfg(cares1_22)]
117 pub fn reinit(&self) -> c_ares::Result<&Self> {
118 self.inner.reinit()?;
119 Ok(self)
120 }
121
122 pub fn set_servers<I, S>(&self, servers: I) -> c_ares::Result<&Self>
128 where
129 I: IntoIterator<Item = S>,
130 S: AsRef<str>,
131 {
132 self.inner.set_servers(servers)?;
133 Ok(self)
134 }
135
136 #[cfg(cares1_24)]
141 pub fn servers(&self) -> Vec<String> {
142 self.inner.servers()
143 }
144
145 pub fn set_local_ipv4(&self, ipv4: Ipv4Addr) -> &Self {
147 self.inner.set_local_ipv4(ipv4);
148 self
149 }
150
151 pub fn set_local_ipv6(&self, ipv6: Ipv6Addr) -> &Self {
153 self.inner.set_local_ipv6(ipv6);
154 self
155 }
156
157 pub fn set_local_device(&self, device: &str) -> c_ares::Result<&Self> {
159 self.inner.set_local_device(device)?;
160 Ok(self)
161 }
162
163 pub fn set_sortlist<I, S>(&self, sortlist: I) -> c_ares::Result<&Self>
170 where
171 I: IntoIterator<Item = S>,
172 S: AsRef<str>,
173 {
174 self.inner.set_sortlist(sortlist)?;
175 Ok(self)
176 }
177
178 #[cfg(cares1_29)]
186 pub fn set_server_state_callback<F>(&self, callback: F) -> &Self
187 where
188 F: Fn(&str, bool, ServerStateFlags) + Send + Sync + 'static,
189 {
190 self.inner.set_server_state_callback(callback);
191 self
192 }
193
194 pub fn query_a(&self, name: &str) -> CAresFuture<c_ares::AResults> {
196 futurize!(self.inner, query_a, name)
197 }
198
199 pub fn search_a(&self, name: &str) -> CAresFuture<c_ares::AResults> {
201 futurize!(self.inner, search_a, name)
202 }
203
204 pub fn query_aaaa(&self, name: &str) -> CAresFuture<c_ares::AAAAResults> {
206 futurize!(self.inner, query_aaaa, name)
207 }
208
209 pub fn search_aaaa(&self, name: &str) -> CAresFuture<c_ares::AAAAResults> {
211 futurize!(self.inner, search_aaaa, name)
212 }
213
214 pub fn query_caa(&self, name: &str) -> CAresFuture<c_ares::CAAResults> {
216 futurize!(self.inner, query_caa, name)
217 }
218
219 pub fn search_caa(&self, name: &str) -> CAresFuture<c_ares::CAAResults> {
221 futurize!(self.inner, search_caa, name)
222 }
223
224 pub fn query_cname(&self, name: &str) -> CAresFuture<c_ares::CNameResults> {
226 futurize!(self.inner, query_cname, name)
227 }
228
229 pub fn search_cname(&self, name: &str) -> CAresFuture<c_ares::CNameResults> {
231 futurize!(self.inner, search_cname, name)
232 }
233
234 pub fn query_mx(&self, name: &str) -> CAresFuture<c_ares::MXResults> {
236 futurize!(self.inner, query_mx, name)
237 }
238
239 pub fn search_mx(&self, name: &str) -> CAresFuture<c_ares::MXResults> {
241 futurize!(self.inner, search_mx, name)
242 }
243
244 pub fn query_naptr(&self, name: &str) -> CAresFuture<c_ares::NAPTRResults> {
246 futurize!(self.inner, query_naptr, name)
247 }
248
249 pub fn search_naptr(&self, name: &str) -> CAresFuture<c_ares::NAPTRResults> {
251 futurize!(self.inner, search_naptr, name)
252 }
253
254 pub fn query_ns(&self, name: &str) -> CAresFuture<c_ares::NSResults> {
256 futurize!(self.inner, query_ns, name)
257 }
258
259 pub fn search_ns(&self, name: &str) -> CAresFuture<c_ares::NSResults> {
261 futurize!(self.inner, search_ns, name)
262 }
263
264 pub fn query_ptr(&self, name: &str) -> CAresFuture<c_ares::PTRResults> {
266 futurize!(self.inner, query_ptr, name)
267 }
268
269 pub fn search_ptr(&self, name: &str) -> CAresFuture<c_ares::PTRResults> {
271 futurize!(self.inner, search_ptr, name)
272 }
273
274 pub fn query_soa(&self, name: &str) -> CAresFuture<c_ares::SOAResult> {
276 futurize!(self.inner, query_soa, name)
277 }
278
279 pub fn search_soa(&self, name: &str) -> CAresFuture<c_ares::SOAResult> {
281 futurize!(self.inner, search_soa, name)
282 }
283
284 pub fn query_srv(&self, name: &str) -> CAresFuture<c_ares::SRVResults> {
286 futurize!(self.inner, query_srv, name)
287 }
288
289 pub fn search_srv(&self, name: &str) -> CAresFuture<c_ares::SRVResults> {
291 futurize!(self.inner, search_srv, name)
292 }
293
294 pub fn query_txt(&self, name: &str) -> CAresFuture<c_ares::TXTResults> {
296 futurize!(self.inner, query_txt, name)
297 }
298
299 pub fn search_txt(&self, name: &str) -> CAresFuture<c_ares::TXTResults> {
301 futurize!(self.inner, search_txt, name)
302 }
303
304 pub fn query_uri(&self, name: &str) -> CAresFuture<c_ares::URIResults> {
306 futurize!(self.inner, query_uri, name)
307 }
308
309 pub fn search_uri(&self, name: &str) -> CAresFuture<c_ares::URIResults> {
311 futurize!(self.inner, search_uri, name)
312 }
313
314 pub fn get_host_by_address(&self, address: &IpAddr) -> CAresFuture<HostResults> {
316 let (sender, receiver) = futures_channel::oneshot::channel();
317 self.inner.get_host_by_address(address, |result| {
318 let _ = sender.send(result.map(Into::into));
319 });
320 let resolver = Arc::clone(&self.inner);
321 CAresFuture::new(receiver, resolver)
322 }
323
324 pub fn get_host_by_name(
326 &self,
327 name: &str,
328 family: c_ares::AddressFamily,
329 ) -> CAresFuture<HostResults> {
330 let (sender, receiver) = futures_channel::oneshot::channel();
331 self.inner.get_host_by_name(name, family, |result| {
332 let _ = sender.send(result.map(Into::into));
333 });
334 let resolver = Arc::clone(&self.inner);
335 CAresFuture::new(receiver, resolver)
336 }
337
338 pub fn get_name_info(
340 &self,
341 address: &SocketAddr,
342 flags: c_ares::NIFlags,
343 ) -> CAresFuture<NameInfoResult> {
344 let (sender, receiver) = futures_channel::oneshot::channel();
345 self.inner.get_name_info(address, flags, |result| {
346 let _ = sender.send(result.map(Into::into));
347 });
348 let resolver = Arc::clone(&self.inner);
349 CAresFuture::new(receiver, resolver)
350 }
351
352 pub fn get_addrinfo(
354 &self,
355 name: &str,
356 service: Option<&str>,
357 hints: &c_ares::AddrInfoHints,
358 ) -> CAresFuture<c_ares::AddrInfoResults> {
359 futurize!(self.inner, get_addrinfo, name, service, hints)
360 }
361
362 pub fn query(&self, name: &str, dns_class: u16, query_type: u16) -> CAresFuture<Vec<u8>> {
369 let (sender, receiver) = futures_channel::oneshot::channel();
370 self.inner.query(name, dns_class, query_type, |result| {
371 let _ = sender.send(result.map(std::borrow::ToOwned::to_owned));
372 });
373 let resolver = Arc::clone(&self.inner);
374 CAresFuture::new(receiver, resolver)
375 }
376
377 pub fn search(&self, name: &str, dns_class: u16, query_type: u16) -> CAresFuture<Vec<u8>> {
384 let (sender, receiver) = futures_channel::oneshot::channel();
385 self.inner.search(name, dns_class, query_type, |result| {
386 let _ = sender.send(result.map(std::borrow::ToOwned::to_owned));
387 });
388 let resolver = Arc::clone(&self.inner);
389 CAresFuture::new(receiver, resolver)
390 }
391
392 #[cfg(cares1_28)]
413 pub fn send_dnsrec(
414 &self,
415 dnsrec: &c_ares::DnsRecord,
416 ) -> c_ares::Result<CAresFuture<c_ares::DnsRecord>> {
417 let (sender, receiver) = futures_channel::oneshot::channel();
418 self.inner.send_dnsrec(dnsrec, |result| {
419 let _ = sender.send(result.and_then(c_ares::DnsRecord::try_clone));
420 })?;
421 let resolver = Arc::clone(&self.inner);
422 Ok(CAresFuture::new(receiver, resolver))
423 }
424
425 #[cfg(cares1_28)]
446 pub fn query_dnsrec(
447 &self,
448 name: &str,
449 dns_class: c_ares::DnsCls,
450 query_type: c_ares::DnsRecordType,
451 ) -> c_ares::Result<CAresFuture<c_ares::DnsRecord>> {
452 let (sender, receiver) = futures_channel::oneshot::channel();
453 self.inner
454 .query_dnsrec(name, dns_class, query_type, |result| {
455 let _ = sender.send(result.and_then(c_ares::DnsRecord::try_clone));
456 })?;
457 let resolver = Arc::clone(&self.inner);
458 Ok(CAresFuture::new(receiver, resolver))
459 }
460
461 #[cfg(cares1_28)]
481 pub fn search_dnsrec(
482 &self,
483 dnsrec: &c_ares::DnsRecord,
484 ) -> c_ares::Result<CAresFuture<c_ares::DnsRecord>> {
485 let (sender, receiver) = futures_channel::oneshot::channel();
486 self.inner.search_dnsrec(dnsrec, |result| {
487 let _ = sender.send(result.and_then(c_ares::DnsRecord::try_clone));
488 })?;
489 let resolver = Arc::clone(&self.inner);
490 Ok(CAresFuture::new(receiver, resolver))
491 }
492
493 #[cfg(cares1_27)]
498 pub fn queue_wait_empty(&self, timeout: Option<std::time::Duration>) -> c_ares::Result<()> {
499 self.inner.queue_wait_empty(timeout)
500 }
501
502 #[cfg(cares1_27)]
504 pub fn queue_active_queries(&self) -> usize {
505 self.inner.queue_active_queries()
506 }
507
508 pub fn cancel(&self) {
510 self.inner.cancel();
511 }
512}
513
514#[cfg(test)]
515mod tests {
516 use super::*;
517 use std::time::Duration;
518
519 fn assert_send<T: Send>() {}
520 fn assert_sync<T: Sync>() {}
521
522 #[test]
523 fn future_resolver_is_send() {
524 assert_send::<FutureResolver>();
525 }
526
527 #[test]
528 fn future_resolver_is_sync() {
529 assert_sync::<FutureResolver>();
530 }
531
532 #[test]
533 fn c_ares_future_is_send() {
534 assert_send::<CAresFuture<c_ares::AResults>>();
535 }
536
537 #[test]
538 fn c_ares_future_is_sync() {
539 assert_sync::<CAresFuture<c_ares::AResults>>();
540 }
541
542 #[test]
543 fn future_resolver_new() {
544 let resolver = FutureResolver::new();
545 assert!(resolver.is_ok());
546 }
547
548 #[test]
549 fn future_resolver_with_options() {
550 let options = Options::new();
551 let resolver = FutureResolver::with_options(options);
552 assert!(resolver.is_ok());
553 }
554
555 #[test]
556 fn future_resolver_with_custom_options() {
557 let mut options = Options::new();
558 options.set_timeout(Duration::from_secs(2)).set_tries(2);
559 let resolver = FutureResolver::with_options(options);
560 assert!(resolver.is_ok());
561 }
562
563 #[test]
564 fn future_resolver_set_local_ipv4() {
565 let resolver = FutureResolver::new().unwrap();
566 let result = resolver.set_local_ipv4(Ipv4Addr::LOCALHOST);
567 assert!(std::ptr::eq(result, &raw const resolver));
568 }
569
570 #[test]
571 fn future_resolver_set_local_ipv6() {
572 let resolver = FutureResolver::new().unwrap();
573 let ipv6 = Ipv6Addr::LOCALHOST;
574 let result = resolver.set_local_ipv6(ipv6);
575 assert!(std::ptr::eq(result, &raw const resolver));
576 }
577
578 #[test]
579 fn future_resolver_set_local_device() {
580 let resolver = FutureResolver::new().unwrap();
581 let result = resolver.set_local_device("lo").unwrap();
582 assert!(std::ptr::eq(result, &raw const resolver));
583 }
584
585 #[test]
586 fn future_resolver_set_servers_valid() {
587 let resolver = FutureResolver::new().unwrap();
588 let result = resolver.set_servers(["8.8.8.8", "8.8.4.4"]);
589 assert!(result.is_ok());
590 }
591
592 #[test]
593 fn future_resolver_set_sortlist_valid() {
594 let resolver = FutureResolver::new().unwrap();
595 let result = resolver.set_sortlist(["130.155.160.0/255.255.240.0"]);
596 assert!(result.is_ok());
597 }
598
599 #[test]
600 fn future_resolver_cancel() {
601 let resolver = FutureResolver::new().unwrap();
602 resolver.cancel(); }
604
605 #[test]
606 #[cfg(cares1_22)]
607 fn future_resolver_reinit() {
608 let resolver = FutureResolver::new().unwrap();
609 let result = resolver.reinit();
610 assert!(result.is_ok());
611 }
612
613 #[test]
614 #[cfg(cares1_24)]
615 fn future_resolver_servers() {
616 let resolver = FutureResolver::new().unwrap();
617 let _ = resolver.set_servers(["8.8.8.8"]);
618 let servers = resolver.servers();
619 assert!(!servers.is_empty());
620 }
621
622 #[test]
623 #[cfg(cares1_27)]
624 fn future_resolver_queue_active_queries() {
625 let resolver = FutureResolver::new().unwrap();
626 assert_eq!(resolver.queue_active_queries(), 0);
627 }
628
629 #[test]
630 #[cfg(cares1_27)]
631 fn future_resolver_queue_wait_empty() {
632 let resolver = FutureResolver::new().unwrap();
633 let result = resolver.queue_wait_empty(Some(std::time::Duration::ZERO));
634 assert!(result.is_ok() || result == Err(c_ares::Error::ENOTIMP));
635 }
636
637 #[test]
638 #[cfg(cares1_29)]
639 fn future_resolver_set_server_state_callback() {
640 let resolver = FutureResolver::new().unwrap();
641 let result = resolver.set_server_state_callback(|_server, _success, _flags| {});
642 assert!(std::ptr::eq(result, &raw const resolver));
643 }
644
645 #[test]
646 fn debug_future_resolver() {
647 let resolver = FutureResolver::new().unwrap();
648 let debug = format!("{resolver:?}");
649 assert!(debug.contains("FutureResolver"));
650 }
651
652 #[test]
653 fn debug_cares_future() {
654 let resolver = FutureResolver::new().unwrap();
655 let future = resolver.query_a("example.com");
656 let debug = format!("{future:?}");
657 assert!(debug.contains("CAresFuture"));
658 }
659}