1use std::ffi::CString;
2use std::mem;
3use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
4#[allow(unused_imports)]
5use std::os::raw::{c_char, c_int, c_void};
6use std::ptr;
7use std::sync::Arc;
8
9use crate::Flags;
10#[cfg(cares1_29)]
11use crate::ServerStateFlags;
12use crate::a::{AResults, query_a_callback};
13use crate::aaaa::{AAAAResults, query_aaaa_callback};
14use crate::caa::{CAAResults, query_caa_callback};
15use crate::cname::{CNameResults, query_cname_callback};
16use crate::error::{Error, Result};
17#[cfg(cares1_34)]
18use crate::events::{FdEvents, ProcessFlags};
19use crate::host::{HostResults, get_host_callback};
20use crate::mx::{MXResults, query_mx_callback};
21use crate::nameinfo::{NameInfoResult, get_name_info_callback};
22use crate::naptr::{NAPTRResults, query_naptr_callback};
23use crate::ni_flags::NIFlags;
24use crate::ns::{NSResults, query_ns_callback};
25use crate::panic;
26use crate::ptr::{PTRResults, query_ptr_callback};
27use crate::query::query_callback;
28use crate::soa::{SOAResult, query_soa_callback};
29use crate::srv::{SRVResults, query_srv_callback};
30#[cfg(cares1_24)]
31use crate::string::AresString;
32use crate::txt::{TXTResults, query_txt_callback};
33use crate::types::{AddressFamily, DnsClass, QueryType, Socket};
34use crate::uri::{URIResults, query_uri_callback};
35#[allow(unused_imports)]
36use crate::utils::{
37 c_string_as_str_unchecked, ipv4_as_in_addr, ipv6_as_in6_addr, socket_addrv4_as_sockaddr_in,
38 socket_addrv6_as_sockaddr_in6,
39};
40use std::sync::Mutex;
41
42static ARES_LIBRARY_LOCK: Mutex<()> = Mutex::new(());
44
45type SocketStateCallback = dyn FnMut(Socket, bool, bool) + Send + 'static;
46
47#[cfg(cares1_29)]
48type ServerStateCallback = dyn FnMut(&str, bool, ServerStateFlags) + Send + 'static;
49
50#[cfg(cares1_34)]
51type PendingWriteCallback = dyn FnMut() + Send + 'static;
52
53#[cfg(cares1_29)]
60pub struct ServerFailoverOptions {
61 retry_chance: u16,
62 retry_delay: usize,
63}
64
65#[cfg(cares1_29)]
66impl Default for ServerFailoverOptions {
67 fn default() -> Self {
68 Self {
69 retry_chance: 10,
70 retry_delay: 5000,
71 }
72 }
73}
74
75#[cfg(cares1_29)]
76impl ServerFailoverOptions {
77 pub fn new() -> Self {
79 Self::default()
80 }
81
82 pub fn set_retry_chance(&mut self, retry_chance: u16) -> &mut Self {
85 self.retry_chance = retry_chance;
86 self
87 }
88
89 pub fn set_retry_delay(&mut self, retry_delay: usize) -> &mut Self {
92 self.retry_delay = retry_delay;
93 self
94 }
95}
96
97pub struct Options {
99 ares_options: c_ares_sys::ares_options,
100 optmask: c_int,
101 domains: Vec<CString>,
102 lookups: Option<CString>,
103 resolvconf_path: Option<CString>,
104 #[cfg(cares1_19)]
105 hosts_path: Option<CString>,
106 socket_state_callback: Option<Arc<SocketStateCallback>>,
107}
108
109impl Default for Options {
110 fn default() -> Self {
111 Self {
112 ares_options: unsafe { mem::MaybeUninit::zeroed().assume_init() },
113 optmask: 0,
114 domains: vec![],
115 lookups: None,
116 resolvconf_path: None,
117 #[cfg(cares1_19)]
118 hosts_path: None,
119 socket_state_callback: None,
120 }
121 }
122}
123
124impl Options {
125 pub fn new() -> Self {
127 Self::default()
128 }
129
130 pub fn set_flags(&mut self, flags: Flags) -> &mut Self {
133 self.ares_options.flags = flags.bits();
134 self.optmask |= c_ares_sys::ARES_OPT_FLAGS;
135 self
136 }
137
138 pub fn set_timeout(&mut self, ms: u32) -> &mut Self {
142 self.ares_options.timeout = ms as c_int;
143 self.optmask |= c_ares_sys::ARES_OPT_TIMEOUTMS;
144 self
145 }
146
147 pub fn set_tries(&mut self, tries: u32) -> &mut Self {
150 self.ares_options.tries = tries as c_int;
151 self.optmask |= c_ares_sys::ARES_OPT_TRIES;
152 self
153 }
154
155 pub fn set_ndots(&mut self, ndots: u32) -> &mut Self {
159 self.ares_options.ndots = ndots as c_int;
160 self.optmask |= c_ares_sys::ARES_OPT_NDOTS;
161 self
162 }
163
164 pub fn set_udp_port(&mut self, udp_port: u16) -> &mut Self {
167 self.ares_options.udp_port = udp_port;
168 self.optmask |= c_ares_sys::ARES_OPT_UDP_PORT;
169 self
170 }
171
172 pub fn set_tcp_port(&mut self, tcp_port: u16) -> &mut Self {
175 self.ares_options.tcp_port = tcp_port;
176 self.optmask |= c_ares_sys::ARES_OPT_TCP_PORT;
177 self
178 }
179
180 pub fn set_domains(&mut self, domains: &[&str]) -> &mut Self {
183 self.domains = domains.iter().map(|&s| CString::new(s).unwrap()).collect();
184 self.optmask |= c_ares_sys::ARES_OPT_DOMAINS;
185 self
186 }
187
188 pub fn set_lookups(&mut self, lookups: &str) -> &mut Self {
192 let c_lookups = CString::new(lookups).unwrap();
193 self.lookups = Some(c_lookups);
194 self.optmask |= c_ares_sys::ARES_OPT_LOOKUPS;
195 self
196 }
197
198 pub fn set_socket_state_callback<F>(&mut self, callback: F) -> &mut Self
205 where
206 F: FnMut(Socket, bool, bool) + Send + 'static,
207 {
208 let boxed_callback = Arc::new(callback);
209 self.ares_options.sock_state_cb = Some(socket_state_callback::<F>);
210 self.ares_options.sock_state_cb_data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
211 self.socket_state_callback = Some(boxed_callback);
212 self.optmask |= c_ares_sys::ARES_OPT_SOCK_STATE_CB;
213 self
214 }
215
216 pub fn set_sock_send_buffer_size(&mut self, size: u32) -> &mut Self {
218 self.ares_options.socket_send_buffer_size = size as c_int;
219 self.optmask |= c_ares_sys::ARES_OPT_SOCK_SNDBUF;
220 self
221 }
222
223 pub fn set_sock_receive_buffer_size(&mut self, size: u32) -> &mut Self {
225 self.ares_options.socket_receive_buffer_size = size as c_int;
226 self.optmask |= c_ares_sys::ARES_OPT_SOCK_RCVBUF;
227 self
228 }
229
230 pub fn set_rotate(&mut self) -> &mut Self {
232 self.optmask &= !c_ares_sys::ARES_OPT_NOROTATE;
233 self.optmask |= c_ares_sys::ARES_OPT_ROTATE;
234 self
235 }
236
237 pub fn set_no_rotate(&mut self) -> &mut Self {
239 self.optmask &= !c_ares_sys::ARES_OPT_ROTATE;
240 self.optmask |= c_ares_sys::ARES_OPT_NOROTATE;
241 self
242 }
243
244 pub fn set_ednspsz(&mut self, size: u32) -> &mut Self {
246 self.ares_options.ednspsz = size as c_int;
247 self.optmask |= c_ares_sys::ARES_OPT_EDNSPSZ;
248 self
249 }
250
251 pub fn set_resolvconf_path(&mut self, resolvconf_path: &str) -> &mut Self {
255 let c_resolvconf_path = CString::new(resolvconf_path).unwrap();
256 self.resolvconf_path = Some(c_resolvconf_path);
257 self.optmask |= c_ares_sys::ARES_OPT_RESOLVCONF;
258 self
259 }
260
261 #[cfg(cares1_19)]
264 pub fn set_hosts_path(&mut self, hosts_path: &str) -> &mut Self {
265 let c_hosts_path = CString::new(hosts_path).unwrap();
266 self.hosts_path = Some(c_hosts_path);
267 self.optmask |= c_ares_sys::ARES_OPT_HOSTS_FILE;
268 self
269 }
270
271 #[cfg(cares1_20)]
275 pub fn set_udp_max_queries(&mut self, udp_max_queries: i32) -> &mut Self {
276 self.ares_options.udp_max_queries = udp_max_queries;
277 self.optmask |= c_ares_sys::ARES_OPT_UDP_MAX_QUERIES;
278 self
279 }
280
281 #[cfg(cares1_22)]
285 pub fn set_max_timeout(&mut self, max_timeout: i32) -> &mut Self {
286 self.ares_options.maxtimeout = max_timeout;
287 self.optmask |= c_ares_sys::ARES_OPT_MAXTIMEOUTMS;
288 self
289 }
290
291 #[cfg(cares1_23)]
298 pub fn set_query_cache_max_ttl(&mut self, qcache_max_ttl: u32) -> &mut Self {
299 self.ares_options.qcache_max_ttl = qcache_max_ttl;
300 self.optmask |= c_ares_sys::ARES_OPT_QUERY_CACHE;
301 self
302 }
303
304 #[cfg(cares1_29)]
309 pub fn set_server_failover_options(
310 &mut self,
311 server_failover_options: &ServerFailoverOptions,
312 ) -> &mut Self {
313 self.ares_options.server_failover_opts.retry_chance = server_failover_options.retry_chance;
314 self.ares_options.server_failover_opts.retry_delay = server_failover_options.retry_delay;
315 self.optmask |= c_ares_sys::ARES_OPT_SERVER_FAILOVER;
316 self
317 }
318}
319
320pub struct Channel {
322 ares_channel: c_ares_sys::ares_channel,
323
324 _socket_state_callback: Option<Arc<SocketStateCallback>>,
326
327 #[cfg(cares1_29)]
329 _server_state_callback: Option<Arc<ServerStateCallback>>,
330
331 #[cfg(cares1_34)]
333 _pending_write_callback: Option<Arc<PendingWriteCallback>>,
334}
335
336impl Channel {
337 pub fn new() -> Result<Self> {
339 let options = Options::default();
340 Self::with_options(options)
341 }
342
343 pub fn with_options(mut options: Options) -> Result<Channel> {
345 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
347 let lib_rc = unsafe { c_ares_sys::ares_library_init(c_ares_sys::ARES_LIB_INIT_ALL) };
348 std::mem::drop(ares_library_lock);
349 if lib_rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
350 return Err(Error::from(lib_rc));
351 }
352
353 let domains: Vec<_> = options.domains.iter().map(|s| s.as_ptr()).collect();
355 options.ares_options.domains = domains.as_ptr().cast_mut().cast();
356 options.ares_options.ndomains = domains.len() as c_int;
357
358 if let Some(c_lookup) = &options.lookups {
360 options.ares_options.lookups = c_lookup.as_ptr().cast_mut()
361 }
362
363 if let Some(c_resolvconf_path) = &options.resolvconf_path {
365 options.ares_options.resolvconf_path = c_resolvconf_path.as_ptr().cast_mut()
366 }
367
368 #[cfg(cares1_19)]
370 if let Some(c_hosts_path) = &options.hosts_path {
371 options.ares_options.hosts_path = c_hosts_path.as_ptr().cast_mut()
372 }
373
374 let mut ares_channel = ptr::null_mut();
376 let channel_rc = unsafe {
377 c_ares_sys::ares_init_options(&mut ares_channel, &options.ares_options, options.optmask)
378 };
379 if channel_rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
380 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
381 unsafe { c_ares_sys::ares_library_cleanup() }
382 std::mem::drop(ares_library_lock);
383 return Err(Error::from(channel_rc));
384 }
385
386 let channel = Channel {
387 ares_channel,
388 _socket_state_callback: options.socket_state_callback,
389 #[cfg(cares1_29)]
390 _server_state_callback: None,
391 #[cfg(cares1_34)]
392 _pending_write_callback: None,
393 };
394 Ok(channel)
395 }
396
397 #[cfg(cares1_22)]
399 pub fn reinit(&mut self) -> Result<&mut Self> {
400 let rc = unsafe { c_ares_sys::ares_reinit(self.ares_channel) };
401 panic::propagate();
402
403 if let Ok(err) = Error::try_from(rc) {
404 return Err(err);
405 }
406 Ok(self)
407 }
408
409 pub fn try_clone(&self) -> Result<Channel> {
411 let mut ares_channel = ptr::null_mut();
412 let rc = unsafe { c_ares_sys::ares_dup(&mut ares_channel, self.ares_channel) };
413 if rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
414 return Err(Error::from(rc));
415 }
416
417 let socket_state_callback = self._socket_state_callback.as_ref().cloned();
418
419 #[cfg(cares1_29)]
420 let server_state_callback = self._server_state_callback.as_ref().cloned();
421
422 #[cfg(cares1_34)]
423 let pending_write_callback = self._pending_write_callback.as_ref().cloned();
424
425 let channel = Channel {
426 ares_channel,
427 _socket_state_callback: socket_state_callback,
428 #[cfg(cares1_29)]
429 _server_state_callback: server_state_callback,
430 #[cfg(cares1_34)]
431 _pending_write_callback: pending_write_callback,
432 };
433 Ok(channel)
434 }
435
436 pub fn process_fd(&mut self, read_fd: Socket, write_fd: Socket) {
443 unsafe { c_ares_sys::ares_process_fd(self.ares_channel, read_fd, write_fd) }
444 panic::propagate();
445 }
446
447 pub fn process(&mut self, read_fds: &mut c_types::fd_set, write_fds: &mut c_types::fd_set) {
450 unsafe { c_ares_sys::ares_process(self.ares_channel, read_fds, write_fds) }
451 panic::propagate();
452 }
453
454 #[cfg(cares1_34)]
458 pub fn process_fds(&mut self, events: &[FdEvents], flags: ProcessFlags) -> Result<()> {
459 let rc = unsafe {
460 c_ares_sys::ares_process_fds(
461 self.ares_channel,
462 events.as_ptr().cast(),
463 events.len(),
464 flags.bits(),
465 )
466 };
467 panic::propagate();
468
469 if let Ok(err) = Error::try_from(rc) {
470 return Err(err);
471 }
472 Ok(())
473 }
474
475 pub fn get_sock(&self) -> GetSock {
478 let mut socks = [0; c_ares_sys::ARES_GETSOCK_MAXNUM];
479 let bitmask = unsafe {
480 c_ares_sys::ares_getsock(
481 self.ares_channel,
482 socks.as_mut_ptr(),
483 c_ares_sys::ARES_GETSOCK_MAXNUM as c_int,
484 )
485 };
486 GetSock::new(socks, bitmask as u32)
487 }
488
489 pub fn fds(&self, read_fds: &mut c_types::fd_set, write_fds: &mut c_types::fd_set) -> u32 {
492 unsafe { c_ares_sys::ares_fds(self.ares_channel, read_fds, write_fds) as u32 }
493 }
494
495 pub fn set_servers(&mut self, servers: &[&str]) -> Result<&mut Self> {
501 let servers_csv = servers.join(",");
502 let c_servers = CString::new(servers_csv).unwrap();
503 let ares_rc = unsafe {
504 c_ares_sys::ares_set_servers_ports_csv(self.ares_channel, c_servers.as_ptr())
505 };
506 if ares_rc == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
507 Ok(self)
508 } else {
509 Err(Error::from(ares_rc))
510 }
511 }
512
513 #[cfg(cares1_24)]
515 pub fn get_servers(&self) -> AresString {
516 let servers = unsafe { c_ares_sys::ares_get_servers_csv(self.ares_channel) };
517 AresString::new(servers)
518 }
519
520 pub fn set_local_ipv4(&mut self, ipv4: Ipv4Addr) -> &mut Self {
522 unsafe { c_ares_sys::ares_set_local_ip4(self.ares_channel, u32::from(ipv4)) }
523 self
524 }
525
526 pub fn set_local_ipv6(&mut self, ipv6: &Ipv6Addr) -> &mut Self {
528 let in6_addr = ipv6_as_in6_addr(ipv6);
529 unsafe {
530 c_ares_sys::ares_set_local_ip6(self.ares_channel, ptr::from_ref(&in6_addr).cast())
531 }
532 self
533 }
534
535 pub fn set_local_device(&mut self, device: &str) -> &mut Self {
537 let c_dev = CString::new(device).unwrap();
538 unsafe { c_ares_sys::ares_set_local_dev(self.ares_channel, c_dev.as_ptr()) }
539 self
540 }
541
542 pub fn set_sortlist(&mut self, sortlist: &[&str]) -> Result<&mut Self> {
549 let sortlist_str = sortlist.join(" ");
550 let c_sortlist = CString::new(sortlist_str).unwrap();
551 let ares_rc =
552 unsafe { c_ares_sys::ares_set_sortlist(self.ares_channel, c_sortlist.as_ptr()) };
553 if ares_rc == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
554 Ok(self)
555 } else {
556 Err(Error::from(ares_rc))
557 }
558 }
559
560 #[cfg(cares1_29)]
568 pub fn set_server_state_callback<F>(&mut self, callback: F) -> &mut Self
569 where
570 F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
571 {
572 let boxed_callback = Arc::new(callback);
573 let data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
574 unsafe {
575 c_ares_sys::ares_set_server_state_callback(
576 self.ares_channel,
577 Some(server_state_callback::<F>),
578 data,
579 )
580 }
581 self._server_state_callback = Some(boxed_callback);
582 self
583 }
584
585 #[cfg(cares1_34)]
588 pub fn set_pending_write_callback<F>(&mut self, callback: F) -> &mut Self
589 where
590 F: FnMut() + Send + 'static,
591 {
592 let boxed_callback = Arc::new(callback);
593 let data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
594 unsafe {
595 c_ares_sys::ares_set_pending_write_cb(
596 self.ares_channel,
597 Some(pending_write_callback::<F>),
598 data,
599 )
600 }
601 self._pending_write_callback = Some(boxed_callback);
602 self
603 }
604
605 pub fn query_a<F>(&mut self, name: &str, handler: F)
609 where
610 F: FnOnce(Result<AResults>) + Send + 'static,
611 {
612 ares_query!(
613 self.ares_channel,
614 name,
615 DnsClass::IN,
616 QueryType::A,
617 query_a_callback::<F>,
618 handler
619 );
620 }
621
622 pub fn search_a<F>(&mut self, name: &str, handler: F)
626 where
627 F: FnOnce(Result<AResults>) + Send + 'static,
628 {
629 ares_search!(
630 self.ares_channel,
631 name,
632 DnsClass::IN,
633 QueryType::A,
634 query_a_callback::<F>,
635 handler
636 );
637 }
638
639 pub fn query_aaaa<F>(&mut self, name: &str, handler: F)
643 where
644 F: FnOnce(Result<AAAAResults>) + Send + 'static,
645 {
646 ares_query!(
647 self.ares_channel,
648 name,
649 DnsClass::IN,
650 QueryType::AAAA,
651 query_aaaa_callback::<F>,
652 handler
653 );
654 }
655
656 pub fn search_aaaa<F>(&mut self, name: &str, handler: F)
661 where
662 F: FnOnce(Result<AAAAResults>) + Send + 'static,
663 {
664 ares_search!(
665 self.ares_channel,
666 name,
667 DnsClass::IN,
668 QueryType::AAAA,
669 query_aaaa_callback::<F>,
670 handler
671 );
672 }
673
674 pub fn query_caa<F>(&mut self, name: &str, handler: F)
678 where
679 F: FnOnce(Result<CAAResults>) + Send + 'static,
680 {
681 ares_query!(
682 self.ares_channel,
683 name,
684 DnsClass::IN,
685 QueryType::CAA,
686 query_caa_callback::<F>,
687 handler
688 );
689 }
690
691 pub fn search_caa<F>(&mut self, name: &str, handler: F)
696 where
697 F: FnOnce(Result<CAAResults>) + Send + 'static,
698 {
699 ares_search!(
700 self.ares_channel,
701 name,
702 DnsClass::IN,
703 QueryType::CAA,
704 query_caa_callback::<F>,
705 handler
706 );
707 }
708
709 pub fn query_cname<F>(&mut self, name: &str, handler: F)
713 where
714 F: FnOnce(Result<CNameResults>) + Send + 'static,
715 {
716 ares_query!(
717 self.ares_channel,
718 name,
719 DnsClass::IN,
720 QueryType::CNAME,
721 query_cname_callback::<F>,
722 handler
723 );
724 }
725
726 pub fn search_cname<F>(&mut self, name: &str, handler: F)
731 where
732 F: FnOnce(Result<CNameResults>) + Send + 'static,
733 {
734 ares_search!(
735 self.ares_channel,
736 name,
737 DnsClass::IN,
738 QueryType::CNAME,
739 query_cname_callback::<F>,
740 handler
741 );
742 }
743
744 pub fn query_mx<F>(&mut self, name: &str, handler: F)
748 where
749 F: FnOnce(Result<MXResults>) + Send + 'static,
750 {
751 ares_query!(
752 self.ares_channel,
753 name,
754 DnsClass::IN,
755 QueryType::MX,
756 query_mx_callback::<F>,
757 handler
758 );
759 }
760
761 pub fn search_mx<F>(&mut self, name: &str, handler: F)
765 where
766 F: FnOnce(Result<MXResults>) + Send + 'static,
767 {
768 ares_search!(
769 self.ares_channel,
770 name,
771 DnsClass::IN,
772 QueryType::MX,
773 query_mx_callback::<F>,
774 handler
775 );
776 }
777
778 pub fn query_naptr<F>(&mut self, name: &str, handler: F)
782 where
783 F: FnOnce(Result<NAPTRResults>) + Send + 'static,
784 {
785 ares_query!(
786 self.ares_channel,
787 name,
788 DnsClass::IN,
789 QueryType::NAPTR,
790 query_naptr_callback::<F>,
791 handler
792 );
793 }
794
795 pub fn search_naptr<F>(&mut self, name: &str, handler: F)
800 where
801 F: FnOnce(Result<NAPTRResults>) + Send + 'static,
802 {
803 ares_search!(
804 self.ares_channel,
805 name,
806 DnsClass::IN,
807 QueryType::NAPTR,
808 query_naptr_callback::<F>,
809 handler
810 );
811 }
812
813 pub fn query_ns<F>(&mut self, name: &str, handler: F)
817 where
818 F: FnOnce(Result<NSResults>) + Send + 'static,
819 {
820 ares_query!(
821 self.ares_channel,
822 name,
823 DnsClass::IN,
824 QueryType::NS,
825 query_ns_callback::<F>,
826 handler
827 );
828 }
829
830 pub fn search_ns<F>(&mut self, name: &str, handler: F)
834 where
835 F: FnOnce(Result<NSResults>) + Send + 'static,
836 {
837 ares_search!(
838 self.ares_channel,
839 name,
840 DnsClass::IN,
841 QueryType::NS,
842 query_ns_callback::<F>,
843 handler
844 );
845 }
846
847 pub fn query_ptr<F>(&mut self, name: &str, handler: F)
851 where
852 F: FnOnce(Result<PTRResults>) + Send + 'static,
853 {
854 ares_query!(
855 self.ares_channel,
856 name,
857 DnsClass::IN,
858 QueryType::PTR,
859 query_ptr_callback::<F>,
860 handler
861 );
862 }
863
864 pub fn search_ptr<F>(&mut self, name: &str, handler: F)
869 where
870 F: FnOnce(Result<PTRResults>) + Send + 'static,
871 {
872 ares_search!(
873 self.ares_channel,
874 name,
875 DnsClass::IN,
876 QueryType::PTR,
877 query_ptr_callback::<F>,
878 handler
879 );
880 }
881
882 pub fn query_soa<F>(&mut self, name: &str, handler: F)
886 where
887 F: FnOnce(Result<SOAResult>) + Send + 'static,
888 {
889 ares_query!(
890 self.ares_channel,
891 name,
892 DnsClass::IN,
893 QueryType::SOA,
894 query_soa_callback::<F>,
895 handler
896 );
897 }
898
899 pub fn search_soa<F>(&mut self, name: &str, handler: F)
904 where
905 F: FnOnce(Result<SOAResult>) + Send + 'static,
906 {
907 ares_search!(
908 self.ares_channel,
909 name,
910 DnsClass::IN,
911 QueryType::SOA,
912 query_soa_callback::<F>,
913 handler
914 );
915 }
916
917 pub fn query_srv<F>(&mut self, name: &str, handler: F)
921 where
922 F: FnOnce(Result<SRVResults>) + Send + 'static,
923 {
924 ares_query!(
925 self.ares_channel,
926 name,
927 DnsClass::IN,
928 QueryType::SRV,
929 query_srv_callback::<F>,
930 handler
931 );
932 }
933
934 pub fn search_srv<F>(&mut self, name: &str, handler: F)
939 where
940 F: FnOnce(Result<SRVResults>) + Send + 'static,
941 {
942 ares_search!(
943 self.ares_channel,
944 name,
945 DnsClass::IN,
946 QueryType::SRV,
947 query_srv_callback::<F>,
948 handler
949 );
950 }
951
952 pub fn query_txt<F>(&mut self, name: &str, handler: F)
956 where
957 F: FnOnce(Result<TXTResults>) + Send + 'static,
958 {
959 ares_query!(
960 self.ares_channel,
961 name,
962 DnsClass::IN,
963 QueryType::TXT,
964 query_txt_callback::<F>,
965 handler
966 );
967 }
968
969 pub fn search_txt<F>(&mut self, name: &str, handler: F)
974 where
975 F: FnOnce(Result<TXTResults>) + Send + 'static,
976 {
977 ares_search!(
978 self.ares_channel,
979 name,
980 DnsClass::IN,
981 QueryType::TXT,
982 query_txt_callback::<F>,
983 handler
984 );
985 }
986
987 pub fn query_uri<F>(&mut self, name: &str, handler: F)
991 where
992 F: FnOnce(Result<URIResults>) + Send + 'static,
993 {
994 ares_query!(
995 self.ares_channel,
996 name,
997 DnsClass::IN,
998 QueryType::URI,
999 query_uri_callback::<F>,
1000 handler
1001 );
1002 }
1003
1004 pub fn search_uri<F>(&mut self, name: &str, handler: F)
1009 where
1010 F: FnOnce(Result<URIResults>) + Send + 'static,
1011 {
1012 ares_search!(
1013 self.ares_channel,
1014 name,
1015 DnsClass::IN,
1016 QueryType::URI,
1017 query_uri_callback::<F>,
1018 handler
1019 );
1020 }
1021
1022 pub fn get_host_by_address<F>(&mut self, address: &IpAddr, handler: F)
1026 where
1027 F: FnOnce(Result<HostResults>) + Send + 'static,
1028 {
1029 let in_addr: c_types::in_addr;
1030 let in6_addr: c_types::in6_addr;
1031 let c_addr = match *address {
1032 IpAddr::V4(v4) => {
1033 in_addr = ipv4_as_in_addr(v4);
1034 ptr::from_ref(&in_addr).cast()
1035 }
1036 IpAddr::V6(ref v6) => {
1037 in6_addr = ipv6_as_in6_addr(v6);
1038 ptr::from_ref(&in6_addr).cast()
1039 }
1040 };
1041 let (family, length) = match *address {
1042 IpAddr::V4(_) => (AddressFamily::INET, mem::size_of::<c_types::in_addr>()),
1043 IpAddr::V6(_) => (AddressFamily::INET6, mem::size_of::<c_types::in6_addr>()),
1044 };
1045 let c_arg = Box::into_raw(Box::new(handler));
1046 unsafe {
1047 c_ares_sys::ares_gethostbyaddr(
1048 self.ares_channel,
1049 c_addr,
1050 length as c_int,
1051 family as c_int,
1052 Some(get_host_callback::<F>),
1053 c_arg.cast(),
1054 )
1055 }
1056 panic::propagate();
1057 }
1058
1059 pub fn get_host_by_name<F>(&mut self, name: &str, family: AddressFamily, handler: F)
1063 where
1064 F: FnOnce(Result<HostResults>) + Send + 'static,
1065 {
1066 let c_name = CString::new(name).unwrap();
1067 let c_arg = Box::into_raw(Box::new(handler));
1068 unsafe {
1069 c_ares_sys::ares_gethostbyname(
1070 self.ares_channel,
1071 c_name.as_ptr(),
1072 family as c_int,
1073 Some(get_host_callback::<F>),
1074 c_arg.cast(),
1075 )
1076 }
1077 panic::propagate();
1078 }
1079
1080 pub fn get_name_info<F>(&mut self, address: &SocketAddr, flags: NIFlags, handler: F)
1086 where
1087 F: FnOnce(Result<NameInfoResult>) + Send + 'static,
1088 {
1089 let sockaddr_in: c_types::sockaddr_in;
1090 let sockaddr_in6: c_types::sockaddr_in6;
1091 let c_addr = match *address {
1092 SocketAddr::V4(ref v4) => {
1093 sockaddr_in = socket_addrv4_as_sockaddr_in(v4);
1094 ptr::from_ref(&sockaddr_in).cast()
1095 }
1096 SocketAddr::V6(ref v6) => {
1097 sockaddr_in6 = socket_addrv6_as_sockaddr_in6(v6);
1098 ptr::from_ref(&sockaddr_in6).cast()
1099 }
1100 };
1101 let length = match *address {
1102 SocketAddr::V4(_) => mem::size_of::<c_types::sockaddr_in>(),
1103 SocketAddr::V6(_) => mem::size_of::<c_types::sockaddr_in6>(),
1104 };
1105 let c_arg = Box::into_raw(Box::new(handler));
1106 unsafe {
1107 c_ares_sys::ares_getnameinfo(
1108 self.ares_channel,
1109 c_addr,
1110 length as c_ares_sys::ares_socklen_t,
1111 flags.bits(),
1112 Some(get_name_info_callback::<F>),
1113 c_arg.cast(),
1114 )
1115 }
1116 panic::propagate();
1117 }
1118
1119 pub fn query<F>(&mut self, name: &str, dns_class: u16, query_type: u16, handler: F)
1128 where
1129 F: FnOnce(Result<&[u8]>) + Send + 'static,
1130 {
1131 ares_query!(
1132 self.ares_channel,
1133 name,
1134 c_int::from(dns_class),
1135 c_int::from(query_type),
1136 query_callback::<F>,
1137 handler
1138 );
1139 }
1140
1141 pub fn search<F>(&mut self, name: &str, dns_class: u16, query_type: u16, handler: F)
1150 where
1151 F: FnOnce(Result<&[u8]>) + Send + 'static,
1152 {
1153 ares_search!(
1154 self.ares_channel,
1155 name,
1156 c_int::from(dns_class),
1157 c_int::from(query_type),
1158 query_callback::<F>,
1159 handler
1160 );
1161 }
1162
1163 pub fn cancel(&mut self) {
1168 unsafe { c_ares_sys::ares_cancel(self.ares_channel) }
1169 panic::propagate();
1170 }
1171
1172 #[cfg(cares1_34)]
1174 pub fn process_pending_write(&mut self) {
1175 unsafe { c_ares_sys::ares_process_pending_write(self.ares_channel) }
1176 panic::propagate();
1177 }
1178}
1179
1180impl Drop for Channel {
1181 fn drop(&mut self) {
1182 unsafe { c_ares_sys::ares_destroy(self.ares_channel) }
1183 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
1184 unsafe { c_ares_sys::ares_library_cleanup() }
1185 std::mem::drop(ares_library_lock);
1186 panic::propagate();
1187 }
1188}
1189
1190unsafe impl Send for Channel {}
1191unsafe impl Sync for Channel {}
1192unsafe impl Send for Options {}
1193unsafe impl Sync for Options {}
1194
1195unsafe extern "C" fn socket_state_callback<F>(
1196 data: *mut c_void,
1197 socket_fd: c_ares_sys::ares_socket_t,
1198 readable: c_int,
1199 writable: c_int,
1200) where
1201 F: FnMut(Socket, bool, bool) + Send + 'static,
1202{
1203 let handler = data.cast::<F>();
1204 let handler = unsafe { &mut *handler };
1205 panic::catch(|| handler(socket_fd, readable != 0, writable != 0));
1206}
1207
1208#[cfg(cares1_29)]
1209unsafe extern "C" fn server_state_callback<F>(
1210 server_string: *const c_char,
1211 success: c_ares_sys::ares_bool_t,
1212 flags: c_int,
1213 data: *mut c_void,
1214) where
1215 F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
1216{
1217 let handler = data.cast::<F>();
1218 let handler = unsafe { &mut *handler };
1219 let server = unsafe { c_string_as_str_unchecked(server_string) };
1220 panic::catch(|| {
1221 handler(
1222 server,
1223 success != c_ares_sys::ares_bool_t::ARES_FALSE,
1224 ServerStateFlags::from_bits_truncate(flags),
1225 )
1226 });
1227}
1228
1229#[cfg(cares1_34)]
1230unsafe extern "C" fn pending_write_callback<F>(data: *mut c_void)
1231where
1232 F: FnMut() + Send + 'static,
1233{
1234 let handler = data.cast::<F>();
1235 let handler = unsafe { &mut *handler };
1236 panic::catch(handler);
1237}
1238
1239#[derive(Clone, Copy, Debug)]
1242pub struct GetSock {
1243 socks: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
1244 bitmask: u32,
1245}
1246
1247impl GetSock {
1248 fn new(
1249 socks: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
1250 bitmask: u32,
1251 ) -> Self {
1252 GetSock { socks, bitmask }
1253 }
1254
1255 pub fn iter(&self) -> GetSockIter<'_> {
1257 GetSockIter {
1258 next: 0,
1259 getsock: self,
1260 }
1261 }
1262}
1263
1264#[derive(Clone, Copy, Debug)]
1268pub struct GetSockIter<'a> {
1269 next: usize,
1270 getsock: &'a GetSock,
1271}
1272
1273impl Iterator for GetSockIter<'_> {
1274 type Item = (Socket, bool, bool);
1275 fn next(&mut self) -> Option<Self::Item> {
1276 let index = self.next;
1277 self.next += 1;
1278 if index >= c_ares_sys::ARES_GETSOCK_MAXNUM {
1279 None
1280 } else {
1281 let bit = 1 << index;
1282 let readable = (self.getsock.bitmask & bit) != 0;
1283 let bit = bit << c_ares_sys::ARES_GETSOCK_MAXNUM;
1284 let writable = (self.getsock.bitmask & bit) != 0;
1285 if readable || writable {
1286 let fd = self.getsock.socks[index];
1287 Some((fd, readable, writable))
1288 } else {
1289 None
1290 }
1291 }
1292 }
1293}
1294
1295impl<'a> IntoIterator for &'a GetSock {
1296 type Item = (Socket, bool, bool);
1297 type IntoIter = GetSockIter<'a>;
1298
1299 fn into_iter(self) -> Self::IntoIter {
1300 self.iter()
1301 }
1302}