1use std::ffi::CString;
2use std::marker::PhantomData;
3use std::mem;
4use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
5#[allow(unused_imports)]
6use std::os::raw::{c_char, c_int, c_void};
7use std::ptr;
8use std::sync::Arc;
9
10use crate::a::{query_a_callback, AResults};
11use crate::aaaa::{query_aaaa_callback, AAAAResults};
12#[cfg(cares1_17)]
13use crate::caa::{query_caa_callback, CAAResults};
14use crate::cname::{query_cname_callback, CNameResults};
15use crate::error::{Error, Result};
16#[cfg(cares1_34)]
17use crate::events::{FdEvents, ProcessFlags};
18use crate::host::{get_host_callback, HostResults};
19use crate::mx::{query_mx_callback, MXResults};
20use crate::nameinfo::{get_name_info_callback, NameInfoResult};
21use crate::naptr::{query_naptr_callback, NAPTRResults};
22use crate::ni_flags::NIFlags;
23use crate::ns::{query_ns_callback, NSResults};
24use crate::panic;
25use crate::ptr::{query_ptr_callback, PTRResults};
26use crate::query::query_callback;
27use crate::soa::{query_soa_callback, SOAResult};
28use crate::srv::{query_srv_callback, SRVResults};
29#[cfg(cares1_24)]
30use crate::string::AresString;
31use crate::txt::{query_txt_callback, TXTResults};
32use crate::types::{AddressFamily, DnsClass, QueryType, Socket};
33use crate::uri::{query_uri_callback, URIResults};
34#[allow(unused_imports)]
35use crate::utils::{
36 c_string_as_str_unchecked, ipv4_as_in_addr, ipv6_as_in6_addr, socket_addrv4_as_sockaddr_in,
37 socket_addrv6_as_sockaddr_in6,
38};
39use crate::Flags;
40#[cfg(cares1_29)]
41use crate::ServerStateFlags;
42use std::sync::Mutex;
43
44static ARES_LIBRARY_LOCK: Mutex<()> = Mutex::new(());
46
47type SocketStateCallback = dyn FnMut(Socket, bool, bool) + Send + 'static;
48
49#[cfg(cares1_29)]
50type ServerStateCallback = dyn FnMut(&str, bool, ServerStateFlags) + Send + 'static;
51
52#[cfg(cares1_34)]
53type PendingWriteCallback = dyn FnMut() + Send + 'static;
54
55#[cfg(cares1_29)]
62pub struct ServerFailoverOptions {
63 retry_chance: u16,
64 retry_delay: usize,
65}
66
67#[cfg(cares1_29)]
68impl Default for ServerFailoverOptions {
69 fn default() -> Self {
70 Self {
71 retry_chance: 10,
72 retry_delay: 5000,
73 }
74 }
75}
76
77#[cfg(cares1_29)]
78impl ServerFailoverOptions {
79 pub fn new() -> Self {
81 Self::default()
82 }
83
84 pub fn set_retry_chance(&mut self, retry_chance: u16) -> &mut Self {
87 self.retry_chance = retry_chance;
88 self
89 }
90
91 pub fn set_retry_delay(&mut self, retry_delay: usize) -> &mut Self {
94 self.retry_delay = retry_delay;
95 self
96 }
97}
98
99pub struct Options {
101 ares_options: c_ares_sys::ares_options,
102 optmask: c_int,
103 domains: Vec<CString>,
104 lookups: Option<CString>,
105 #[cfg(cares1_15)]
106 resolvconf_path: Option<CString>,
107 #[cfg(cares1_19)]
108 hosts_path: Option<CString>,
109 socket_state_callback: Option<Arc<SocketStateCallback>>,
110}
111
112impl Default for Options {
113 fn default() -> Self {
114 Self {
115 ares_options: unsafe { mem::MaybeUninit::zeroed().assume_init() },
116 optmask: 0,
117 domains: vec![],
118 lookups: None,
119 #[cfg(cares1_15)]
120 resolvconf_path: None,
121 #[cfg(cares1_19)]
122 hosts_path: None,
123 socket_state_callback: None,
124 }
125 }
126}
127
128impl Options {
129 pub fn new() -> Self {
131 Self::default()
132 }
133
134 pub fn set_flags(&mut self, flags: Flags) -> &mut Self {
137 self.ares_options.flags = flags.bits();
138 self.optmask |= c_ares_sys::ARES_OPT_FLAGS;
139 self
140 }
141
142 pub fn set_timeout(&mut self, ms: u32) -> &mut Self {
146 self.ares_options.timeout = ms as c_int;
147 self.optmask |= c_ares_sys::ARES_OPT_TIMEOUTMS;
148 self
149 }
150
151 pub fn set_tries(&mut self, tries: u32) -> &mut Self {
154 self.ares_options.tries = tries as c_int;
155 self.optmask |= c_ares_sys::ARES_OPT_TRIES;
156 self
157 }
158
159 pub fn set_ndots(&mut self, ndots: u32) -> &mut Self {
163 self.ares_options.ndots = ndots as c_int;
164 self.optmask |= c_ares_sys::ARES_OPT_NDOTS;
165 self
166 }
167
168 pub fn set_udp_port(&mut self, udp_port: u16) -> &mut Self {
171 self.ares_options.udp_port = udp_port;
172 self.optmask |= c_ares_sys::ARES_OPT_UDP_PORT;
173 self
174 }
175
176 pub fn set_tcp_port(&mut self, tcp_port: u16) -> &mut Self {
179 self.ares_options.tcp_port = tcp_port;
180 self.optmask |= c_ares_sys::ARES_OPT_TCP_PORT;
181 self
182 }
183
184 pub fn set_domains(&mut self, domains: &[&str]) -> &mut Self {
187 self.domains = domains.iter().map(|&s| CString::new(s).unwrap()).collect();
188 self.optmask |= c_ares_sys::ARES_OPT_DOMAINS;
189 self
190 }
191
192 pub fn set_lookups(&mut self, lookups: &str) -> &mut Self {
196 let c_lookups = CString::new(lookups).unwrap();
197 self.lookups = Some(c_lookups);
198 self.optmask |= c_ares_sys::ARES_OPT_LOOKUPS;
199 self
200 }
201
202 pub fn set_socket_state_callback<F>(&mut self, callback: F) -> &mut Self
209 where
210 F: FnMut(Socket, bool, bool) + Send + 'static,
211 {
212 let boxed_callback = Arc::new(callback);
213 self.ares_options.sock_state_cb = Some(socket_state_callback::<F>);
214 self.ares_options.sock_state_cb_data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
215 self.socket_state_callback = Some(boxed_callback);
216 self.optmask |= c_ares_sys::ARES_OPT_SOCK_STATE_CB;
217 self
218 }
219
220 pub fn set_sock_send_buffer_size(&mut self, size: u32) -> &mut Self {
222 self.ares_options.socket_send_buffer_size = size as c_int;
223 self.optmask |= c_ares_sys::ARES_OPT_SOCK_SNDBUF;
224 self
225 }
226
227 pub fn set_sock_receive_buffer_size(&mut self, size: u32) -> &mut Self {
229 self.ares_options.socket_receive_buffer_size = size as c_int;
230 self.optmask |= c_ares_sys::ARES_OPT_SOCK_RCVBUF;
231 self
232 }
233
234 pub fn set_rotate(&mut self) -> &mut Self {
236 self.optmask &= !c_ares_sys::ARES_OPT_NOROTATE;
237 self.optmask |= c_ares_sys::ARES_OPT_ROTATE;
238 self
239 }
240
241 pub fn set_no_rotate(&mut self) -> &mut Self {
243 self.optmask &= !c_ares_sys::ARES_OPT_ROTATE;
244 self.optmask |= c_ares_sys::ARES_OPT_NOROTATE;
245 self
246 }
247
248 pub fn set_ednspsz(&mut self, size: u32) -> &mut Self {
250 self.ares_options.ednspsz = size as c_int;
251 self.optmask |= c_ares_sys::ARES_OPT_EDNSPSZ;
252 self
253 }
254
255 #[cfg(cares1_15)]
259 pub fn set_resolvconf_path(&mut self, resolvconf_path: &str) -> &mut Self {
260 let c_resolvconf_path = CString::new(resolvconf_path).unwrap();
261 self.resolvconf_path = Some(c_resolvconf_path);
262 self.optmask |= c_ares_sys::ARES_OPT_RESOLVCONF;
263 self
264 }
265
266 #[cfg(cares1_19)]
269 pub fn set_hosts_path(&mut self, hosts_path: &str) -> &mut Self {
270 let c_hosts_path = CString::new(hosts_path).unwrap();
271 self.hosts_path = Some(c_hosts_path);
272 self.optmask |= c_ares_sys::ARES_OPT_HOSTS_FILE;
273 self
274 }
275
276 #[cfg(cares1_20)]
280 pub fn set_udp_max_queries(&mut self, udp_max_queries: i32) -> &mut Self {
281 self.ares_options.udp_max_queries = udp_max_queries;
282 self.optmask |= c_ares_sys::ARES_OPT_UDP_MAX_QUERIES;
283 self
284 }
285
286 #[cfg(cares1_22)]
290 pub fn set_max_timeout(&mut self, max_timeout: i32) -> &mut Self {
291 self.ares_options.maxtimeout = max_timeout;
292 self.optmask |= c_ares_sys::ARES_OPT_MAXTIMEOUTMS;
293 self
294 }
295
296 #[cfg(cares1_23)]
303 pub fn set_query_cache_max_ttl(&mut self, qcache_max_ttl: u32) -> &mut Self {
304 self.ares_options.qcache_max_ttl = qcache_max_ttl;
305 self.optmask |= c_ares_sys::ARES_OPT_QUERY_CACHE;
306 self
307 }
308
309 #[cfg(cares1_29)]
314 pub fn set_server_failover_options(
315 &mut self,
316 server_failover_options: &ServerFailoverOptions,
317 ) -> &mut Self {
318 self.ares_options.server_failover_opts.retry_chance = server_failover_options.retry_chance;
319 self.ares_options.server_failover_opts.retry_delay = server_failover_options.retry_delay;
320 self.optmask |= c_ares_sys::ARES_OPT_SERVER_FAILOVER;
321 self
322 }
323}
324
325pub struct Channel {
327 ares_channel: c_ares_sys::ares_channel,
328 phantom: PhantomData<c_ares_sys::ares_channeldata>,
329
330 _socket_state_callback: Option<Arc<SocketStateCallback>>,
332
333 #[cfg(cares1_29)]
335 _server_state_callback: Option<Arc<ServerStateCallback>>,
336
337 #[cfg(cares1_34)]
339 _pending_write_callback: Option<Arc<PendingWriteCallback>>,
340}
341
342impl Channel {
343 pub fn new() -> Result<Self> {
345 let options = Options::default();
346 Self::with_options(options)
347 }
348
349 pub fn with_options(mut options: Options) -> Result<Channel> {
351 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
353 let lib_rc = unsafe { c_ares_sys::ares_library_init(c_ares_sys::ARES_LIB_INIT_ALL) };
354 std::mem::drop(ares_library_lock);
355 if lib_rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
356 return Err(Error::from(lib_rc));
357 }
358
359 let domains: Vec<_> = options.domains.iter().map(|s| s.as_ptr()).collect();
361 options.ares_options.domains = domains.as_ptr().cast_mut().cast();
362 options.ares_options.ndomains = domains.len() as c_int;
363
364 if let Some(c_lookup) = &options.lookups {
366 options.ares_options.lookups = c_lookup.as_ptr().cast_mut()
367 }
368
369 #[cfg(cares1_15)]
371 if let Some(c_resolvconf_path) = &options.resolvconf_path {
372 options.ares_options.resolvconf_path = c_resolvconf_path.as_ptr().cast_mut()
373 }
374
375 #[cfg(cares1_19)]
377 if let Some(c_hosts_path) = &options.hosts_path {
378 options.ares_options.hosts_path = c_hosts_path.as_ptr().cast_mut()
379 }
380
381 let mut ares_channel = ptr::null_mut();
383 let channel_rc = unsafe {
384 c_ares_sys::ares_init_options(&mut ares_channel, &options.ares_options, options.optmask)
385 };
386 if channel_rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
387 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
388 unsafe { c_ares_sys::ares_library_cleanup() }
389 std::mem::drop(ares_library_lock);
390 return Err(Error::from(channel_rc));
391 }
392
393 let channel = Channel {
394 ares_channel,
395 phantom: PhantomData,
396 _socket_state_callback: options.socket_state_callback,
397 #[cfg(cares1_29)]
398 _server_state_callback: None,
399 #[cfg(cares1_34)]
400 _pending_write_callback: None,
401 };
402 Ok(channel)
403 }
404
405 #[cfg(cares1_22)]
407 pub fn reinit(&mut self) -> Result<&mut Self> {
408 let rc = unsafe { c_ares_sys::ares_reinit(self.ares_channel) };
409 panic::propagate();
410
411 if let Ok(err) = Error::try_from(rc) {
412 return Err(err);
413 }
414 Ok(self)
415 }
416
417 pub fn try_clone(&self) -> Result<Channel> {
419 let mut ares_channel = ptr::null_mut();
420 let rc = unsafe { c_ares_sys::ares_dup(&mut ares_channel, self.ares_channel) };
421 if rc != c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
422 return Err(Error::from(rc));
423 }
424
425 let socket_state_callback = self._socket_state_callback.as_ref().cloned();
426
427 #[cfg(cares1_29)]
428 let server_state_callback = self._server_state_callback.as_ref().cloned();
429
430 #[cfg(cares1_34)]
431 let pending_write_callback = self._pending_write_callback.as_ref().cloned();
432
433 let channel = Channel {
434 ares_channel,
435 phantom: PhantomData,
436 _socket_state_callback: socket_state_callback,
437 #[cfg(cares1_29)]
438 _server_state_callback: server_state_callback,
439 #[cfg(cares1_34)]
440 _pending_write_callback: pending_write_callback,
441 };
442 Ok(channel)
443 }
444
445 pub fn process_fd(&mut self, read_fd: Socket, write_fd: Socket) {
452 unsafe { c_ares_sys::ares_process_fd(self.ares_channel, read_fd, write_fd) }
453 panic::propagate();
454 }
455
456 pub fn process(&mut self, read_fds: &mut c_types::fd_set, write_fds: &mut c_types::fd_set) {
459 unsafe { c_ares_sys::ares_process(self.ares_channel, read_fds, write_fds) }
460 panic::propagate();
461 }
462
463 #[cfg(cares1_34)]
467 pub fn process_fds(&mut self, events: &[FdEvents], flags: ProcessFlags) -> Result<()> {
468 let rc = unsafe {
469 c_ares_sys::ares_process_fds(
470 self.ares_channel,
471 events.as_ptr().cast(),
472 events.len(),
473 flags.bits(),
474 )
475 };
476 panic::propagate();
477
478 if let Ok(err) = Error::try_from(rc) {
479 return Err(err);
480 }
481 Ok(())
482 }
483
484 pub fn get_sock(&self) -> GetSock {
487 let mut socks = [0; c_ares_sys::ARES_GETSOCK_MAXNUM];
488 let bitmask = unsafe {
489 c_ares_sys::ares_getsock(
490 self.ares_channel,
491 socks.as_mut_ptr(),
492 c_ares_sys::ARES_GETSOCK_MAXNUM as c_int,
493 )
494 };
495 GetSock::new(socks, bitmask as u32)
496 }
497
498 pub fn fds(&self, read_fds: &mut c_types::fd_set, write_fds: &mut c_types::fd_set) -> u32 {
501 unsafe { c_ares_sys::ares_fds(self.ares_channel, read_fds, write_fds) as u32 }
502 }
503
504 pub fn set_servers(&mut self, servers: &[&str]) -> Result<&mut Self> {
510 let servers_csv = servers.join(",");
511 let c_servers = CString::new(servers_csv).unwrap();
512 let ares_rc = unsafe {
513 c_ares_sys::ares_set_servers_ports_csv(self.ares_channel, c_servers.as_ptr())
514 };
515 if ares_rc == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
516 Ok(self)
517 } else {
518 Err(Error::from(ares_rc))
519 }
520 }
521
522 #[cfg(cares1_24)]
524 pub fn get_servers(&self) -> AresString {
525 let servers = unsafe { c_ares_sys::ares_get_servers_csv(self.ares_channel) };
526 AresString::new(servers)
527 }
528
529 pub fn set_local_ipv4(&mut self, ipv4: Ipv4Addr) -> &mut Self {
531 unsafe { c_ares_sys::ares_set_local_ip4(self.ares_channel, u32::from(ipv4)) }
532 self
533 }
534
535 pub fn set_local_ipv6(&mut self, ipv6: &Ipv6Addr) -> &mut Self {
537 let in6_addr = ipv6_as_in6_addr(ipv6);
538 unsafe {
539 c_ares_sys::ares_set_local_ip6(self.ares_channel, ptr::from_ref(&in6_addr).cast())
540 }
541 self
542 }
543
544 pub fn set_local_device(&mut self, device: &str) -> &mut Self {
546 let c_dev = CString::new(device).unwrap();
547 unsafe { c_ares_sys::ares_set_local_dev(self.ares_channel, c_dev.as_ptr()) }
548 self
549 }
550
551 pub fn set_sortlist(&mut self, sortlist: &[&str]) -> Result<&mut Self> {
558 let sortlist_str = sortlist.join(" ");
559 let c_sortlist = CString::new(sortlist_str).unwrap();
560 let ares_rc =
561 unsafe { c_ares_sys::ares_set_sortlist(self.ares_channel, c_sortlist.as_ptr()) };
562 if ares_rc == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
563 Ok(self)
564 } else {
565 Err(Error::from(ares_rc))
566 }
567 }
568
569 #[cfg(cares1_29)]
577 pub fn set_server_state_callback<F>(&mut self, callback: F) -> &mut Self
578 where
579 F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
580 {
581 let boxed_callback = Arc::new(callback);
582 let data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
583 unsafe {
584 c_ares_sys::ares_set_server_state_callback(
585 self.ares_channel,
586 Some(server_state_callback::<F>),
587 data,
588 )
589 }
590 self._server_state_callback = Some(boxed_callback);
591 self
592 }
593
594 #[cfg(cares1_34)]
597 pub fn set_pending_write_callback<F>(&mut self, callback: F) -> &mut Self
598 where
599 F: FnMut() + Send + 'static,
600 {
601 let boxed_callback = Arc::new(callback);
602 let data = ptr::from_ref(&*boxed_callback).cast_mut().cast();
603 unsafe {
604 c_ares_sys::ares_set_pending_write_cb(
605 self.ares_channel,
606 Some(pending_write_callback::<F>),
607 data,
608 )
609 }
610 self._pending_write_callback = Some(boxed_callback);
611 self
612 }
613
614 pub fn query_a<F>(&mut self, name: &str, handler: F)
618 where
619 F: FnOnce(Result<AResults>) + Send + 'static,
620 {
621 ares_query!(
622 self.ares_channel,
623 name,
624 DnsClass::IN,
625 QueryType::A,
626 query_a_callback::<F>,
627 handler
628 );
629 }
630
631 pub fn search_a<F>(&mut self, name: &str, handler: F)
635 where
636 F: FnOnce(Result<AResults>) + Send + 'static,
637 {
638 ares_search!(
639 self.ares_channel,
640 name,
641 DnsClass::IN,
642 QueryType::A,
643 query_a_callback::<F>,
644 handler
645 );
646 }
647
648 pub fn query_aaaa<F>(&mut self, name: &str, handler: F)
652 where
653 F: FnOnce(Result<AAAAResults>) + Send + 'static,
654 {
655 ares_query!(
656 self.ares_channel,
657 name,
658 DnsClass::IN,
659 QueryType::AAAA,
660 query_aaaa_callback::<F>,
661 handler
662 );
663 }
664
665 pub fn search_aaaa<F>(&mut self, name: &str, handler: F)
670 where
671 F: FnOnce(Result<AAAAResults>) + Send + 'static,
672 {
673 ares_search!(
674 self.ares_channel,
675 name,
676 DnsClass::IN,
677 QueryType::AAAA,
678 query_aaaa_callback::<F>,
679 handler
680 );
681 }
682
683 #[cfg(cares1_17)]
687 pub fn query_caa<F>(&mut self, name: &str, handler: F)
688 where
689 F: FnOnce(Result<CAAResults>) + Send + 'static,
690 {
691 ares_query!(
692 self.ares_channel,
693 name,
694 DnsClass::IN,
695 QueryType::CAA,
696 query_caa_callback::<F>,
697 handler
698 );
699 }
700
701 #[cfg(cares1_17)]
706 pub fn search_caa<F>(&mut self, name: &str, handler: F)
707 where
708 F: FnOnce(Result<CAAResults>) + Send + 'static,
709 {
710 ares_search!(
711 self.ares_channel,
712 name,
713 DnsClass::IN,
714 QueryType::CAA,
715 query_caa_callback::<F>,
716 handler
717 );
718 }
719
720 pub fn query_cname<F>(&mut self, name: &str, handler: F)
724 where
725 F: FnOnce(Result<CNameResults>) + Send + 'static,
726 {
727 ares_query!(
728 self.ares_channel,
729 name,
730 DnsClass::IN,
731 QueryType::CNAME,
732 query_cname_callback::<F>,
733 handler
734 );
735 }
736
737 pub fn search_cname<F>(&mut self, name: &str, handler: F)
742 where
743 F: FnOnce(Result<CNameResults>) + Send + 'static,
744 {
745 ares_search!(
746 self.ares_channel,
747 name,
748 DnsClass::IN,
749 QueryType::CNAME,
750 query_cname_callback::<F>,
751 handler
752 );
753 }
754
755 pub fn query_mx<F>(&mut self, name: &str, handler: F)
759 where
760 F: FnOnce(Result<MXResults>) + Send + 'static,
761 {
762 ares_query!(
763 self.ares_channel,
764 name,
765 DnsClass::IN,
766 QueryType::MX,
767 query_mx_callback::<F>,
768 handler
769 );
770 }
771
772 pub fn search_mx<F>(&mut self, name: &str, handler: F)
776 where
777 F: FnOnce(Result<MXResults>) + Send + 'static,
778 {
779 ares_search!(
780 self.ares_channel,
781 name,
782 DnsClass::IN,
783 QueryType::MX,
784 query_mx_callback::<F>,
785 handler
786 );
787 }
788
789 pub fn query_naptr<F>(&mut self, name: &str, handler: F)
793 where
794 F: FnOnce(Result<NAPTRResults>) + Send + 'static,
795 {
796 ares_query!(
797 self.ares_channel,
798 name,
799 DnsClass::IN,
800 QueryType::NAPTR,
801 query_naptr_callback::<F>,
802 handler
803 );
804 }
805
806 pub fn search_naptr<F>(&mut self, name: &str, handler: F)
811 where
812 F: FnOnce(Result<NAPTRResults>) + Send + 'static,
813 {
814 ares_search!(
815 self.ares_channel,
816 name,
817 DnsClass::IN,
818 QueryType::NAPTR,
819 query_naptr_callback::<F>,
820 handler
821 );
822 }
823
824 pub fn query_ns<F>(&mut self, name: &str, handler: F)
828 where
829 F: FnOnce(Result<NSResults>) + Send + 'static,
830 {
831 ares_query!(
832 self.ares_channel,
833 name,
834 DnsClass::IN,
835 QueryType::NS,
836 query_ns_callback::<F>,
837 handler
838 );
839 }
840
841 pub fn search_ns<F>(&mut self, name: &str, handler: F)
845 where
846 F: FnOnce(Result<NSResults>) + Send + 'static,
847 {
848 ares_search!(
849 self.ares_channel,
850 name,
851 DnsClass::IN,
852 QueryType::NS,
853 query_ns_callback::<F>,
854 handler
855 );
856 }
857
858 pub fn query_ptr<F>(&mut self, name: &str, handler: F)
862 where
863 F: FnOnce(Result<PTRResults>) + Send + 'static,
864 {
865 ares_query!(
866 self.ares_channel,
867 name,
868 DnsClass::IN,
869 QueryType::PTR,
870 query_ptr_callback::<F>,
871 handler
872 );
873 }
874
875 pub fn search_ptr<F>(&mut self, name: &str, handler: F)
880 where
881 F: FnOnce(Result<PTRResults>) + Send + 'static,
882 {
883 ares_search!(
884 self.ares_channel,
885 name,
886 DnsClass::IN,
887 QueryType::PTR,
888 query_ptr_callback::<F>,
889 handler
890 );
891 }
892
893 pub fn query_soa<F>(&mut self, name: &str, handler: F)
897 where
898 F: FnOnce(Result<SOAResult>) + Send + 'static,
899 {
900 ares_query!(
901 self.ares_channel,
902 name,
903 DnsClass::IN,
904 QueryType::SOA,
905 query_soa_callback::<F>,
906 handler
907 );
908 }
909
910 pub fn search_soa<F>(&mut self, name: &str, handler: F)
915 where
916 F: FnOnce(Result<SOAResult>) + Send + 'static,
917 {
918 ares_search!(
919 self.ares_channel,
920 name,
921 DnsClass::IN,
922 QueryType::SOA,
923 query_soa_callback::<F>,
924 handler
925 );
926 }
927
928 pub fn query_srv<F>(&mut self, name: &str, handler: F)
932 where
933 F: FnOnce(Result<SRVResults>) + Send + 'static,
934 {
935 ares_query!(
936 self.ares_channel,
937 name,
938 DnsClass::IN,
939 QueryType::SRV,
940 query_srv_callback::<F>,
941 handler
942 );
943 }
944
945 pub fn search_srv<F>(&mut self, name: &str, handler: F)
950 where
951 F: FnOnce(Result<SRVResults>) + Send + 'static,
952 {
953 ares_search!(
954 self.ares_channel,
955 name,
956 DnsClass::IN,
957 QueryType::SRV,
958 query_srv_callback::<F>,
959 handler
960 );
961 }
962
963 pub fn query_txt<F>(&mut self, name: &str, handler: F)
967 where
968 F: FnOnce(Result<TXTResults>) + Send + 'static,
969 {
970 ares_query!(
971 self.ares_channel,
972 name,
973 DnsClass::IN,
974 QueryType::TXT,
975 query_txt_callback::<F>,
976 handler
977 );
978 }
979
980 pub fn search_txt<F>(&mut self, name: &str, handler: F)
985 where
986 F: FnOnce(Result<TXTResults>) + Send + 'static,
987 {
988 ares_search!(
989 self.ares_channel,
990 name,
991 DnsClass::IN,
992 QueryType::TXT,
993 query_txt_callback::<F>,
994 handler
995 );
996 }
997
998 pub fn query_uri<F>(&mut self, name: &str, handler: F)
1002 where
1003 F: FnOnce(Result<URIResults>) + Send + 'static,
1004 {
1005 ares_query!(
1006 self.ares_channel,
1007 name,
1008 DnsClass::IN,
1009 QueryType::URI,
1010 query_uri_callback::<F>,
1011 handler
1012 );
1013 }
1014
1015 pub fn search_uri<F>(&mut self, name: &str, handler: F)
1020 where
1021 F: FnOnce(Result<URIResults>) + Send + 'static,
1022 {
1023 ares_search!(
1024 self.ares_channel,
1025 name,
1026 DnsClass::IN,
1027 QueryType::URI,
1028 query_uri_callback::<F>,
1029 handler
1030 );
1031 }
1032
1033 pub fn get_host_by_address<F>(&mut self, address: &IpAddr, handler: F)
1037 where
1038 F: FnOnce(Result<HostResults>) + Send + 'static,
1039 {
1040 let in_addr: c_types::in_addr;
1041 let in6_addr: c_types::in6_addr;
1042 let c_addr = match *address {
1043 IpAddr::V4(v4) => {
1044 in_addr = ipv4_as_in_addr(v4);
1045 ptr::from_ref(&in_addr).cast()
1046 }
1047 IpAddr::V6(ref v6) => {
1048 in6_addr = ipv6_as_in6_addr(v6);
1049 ptr::from_ref(&in6_addr).cast()
1050 }
1051 };
1052 let (family, length) = match *address {
1053 IpAddr::V4(_) => (AddressFamily::INET, mem::size_of::<c_types::in_addr>()),
1054 IpAddr::V6(_) => (AddressFamily::INET6, mem::size_of::<c_types::in6_addr>()),
1055 };
1056 let c_arg = Box::into_raw(Box::new(handler));
1057 unsafe {
1058 c_ares_sys::ares_gethostbyaddr(
1059 self.ares_channel,
1060 c_addr,
1061 length as c_int,
1062 family as c_int,
1063 Some(get_host_callback::<F>),
1064 c_arg.cast(),
1065 )
1066 }
1067 panic::propagate();
1068 }
1069
1070 pub fn get_host_by_name<F>(&mut self, name: &str, family: AddressFamily, handler: F)
1074 where
1075 F: FnOnce(Result<HostResults>) + Send + 'static,
1076 {
1077 let c_name = CString::new(name).unwrap();
1078 let c_arg = Box::into_raw(Box::new(handler));
1079 unsafe {
1080 c_ares_sys::ares_gethostbyname(
1081 self.ares_channel,
1082 c_name.as_ptr(),
1083 family as c_int,
1084 Some(get_host_callback::<F>),
1085 c_arg.cast(),
1086 )
1087 }
1088 panic::propagate();
1089 }
1090
1091 pub fn get_name_info<F>(&mut self, address: &SocketAddr, flags: NIFlags, handler: F)
1097 where
1098 F: FnOnce(Result<NameInfoResult>) + Send + 'static,
1099 {
1100 let sockaddr_in: c_types::sockaddr_in;
1101 let sockaddr_in6: c_types::sockaddr_in6;
1102 let c_addr = match *address {
1103 SocketAddr::V4(ref v4) => {
1104 sockaddr_in = socket_addrv4_as_sockaddr_in(v4);
1105 ptr::from_ref(&sockaddr_in).cast()
1106 }
1107 SocketAddr::V6(ref v6) => {
1108 sockaddr_in6 = socket_addrv6_as_sockaddr_in6(v6);
1109 ptr::from_ref(&sockaddr_in6).cast()
1110 }
1111 };
1112 let length = match *address {
1113 SocketAddr::V4(_) => mem::size_of::<c_types::sockaddr_in>(),
1114 SocketAddr::V6(_) => mem::size_of::<c_types::sockaddr_in6>(),
1115 };
1116 let c_arg = Box::into_raw(Box::new(handler));
1117 unsafe {
1118 c_ares_sys::ares_getnameinfo(
1119 self.ares_channel,
1120 c_addr,
1121 length as c_ares_sys::ares_socklen_t,
1122 flags.bits(),
1123 Some(get_name_info_callback::<F>),
1124 c_arg.cast(),
1125 )
1126 }
1127 panic::propagate();
1128 }
1129
1130 pub fn query<F>(&mut self, name: &str, dns_class: u16, query_type: u16, handler: F)
1139 where
1140 F: FnOnce(Result<&[u8]>) + Send + 'static,
1141 {
1142 ares_query!(
1143 self.ares_channel,
1144 name,
1145 c_int::from(dns_class),
1146 c_int::from(query_type),
1147 query_callback::<F>,
1148 handler
1149 );
1150 }
1151
1152 pub fn search<F>(&mut self, name: &str, dns_class: u16, query_type: u16, handler: F)
1161 where
1162 F: FnOnce(Result<&[u8]>) + Send + 'static,
1163 {
1164 ares_search!(
1165 self.ares_channel,
1166 name,
1167 c_int::from(dns_class),
1168 c_int::from(query_type),
1169 query_callback::<F>,
1170 handler
1171 );
1172 }
1173
1174 pub fn cancel(&mut self) {
1179 unsafe { c_ares_sys::ares_cancel(self.ares_channel) }
1180 panic::propagate();
1181 }
1182
1183 #[cfg(cares1_34)]
1185 pub fn process_pending_write(&mut self) {
1186 unsafe { c_ares_sys::ares_process_pending_write(self.ares_channel) }
1187 panic::propagate();
1188 }
1189}
1190
1191impl Drop for Channel {
1192 fn drop(&mut self) {
1193 unsafe { c_ares_sys::ares_destroy(self.ares_channel) }
1194 let ares_library_lock = ARES_LIBRARY_LOCK.lock().unwrap();
1195 unsafe { c_ares_sys::ares_library_cleanup() }
1196 std::mem::drop(ares_library_lock);
1197 panic::propagate();
1198 }
1199}
1200
1201unsafe impl Send for Channel {}
1202unsafe impl Sync for Channel {}
1203unsafe impl Send for Options {}
1204unsafe impl Sync for Options {}
1205
1206unsafe extern "C" fn socket_state_callback<F>(
1207 data: *mut c_void,
1208 socket_fd: c_ares_sys::ares_socket_t,
1209 readable: c_int,
1210 writable: c_int,
1211) where
1212 F: FnMut(Socket, bool, bool) + Send + 'static,
1213{
1214 let handler = data.cast::<F>();
1215 let handler = unsafe { &mut *handler };
1216 panic::catch(|| handler(socket_fd, readable != 0, writable != 0));
1217}
1218
1219#[cfg(cares1_29)]
1220unsafe extern "C" fn server_state_callback<F>(
1221 server_string: *const c_char,
1222 success: c_ares_sys::ares_bool_t,
1223 flags: c_int,
1224 data: *mut c_void,
1225) where
1226 F: FnMut(&str, bool, ServerStateFlags) + Send + 'static,
1227{
1228 let handler = data.cast::<F>();
1229 let handler = unsafe { &mut *handler };
1230 let server = c_string_as_str_unchecked(server_string);
1231 panic::catch(|| {
1232 handler(
1233 server,
1234 success != c_ares_sys::ares_bool_t::ARES_FALSE,
1235 ServerStateFlags::from_bits_truncate(flags),
1236 )
1237 });
1238}
1239
1240#[cfg(cares1_34)]
1241unsafe extern "C" fn pending_write_callback<F>(data: *mut c_void)
1242where
1243 F: FnMut() + Send + 'static,
1244{
1245 let handler = data.cast::<F>();
1246 let handler = unsafe { &mut *handler };
1247 panic::catch(handler);
1248}
1249
1250#[derive(Clone, Copy, Debug)]
1253pub struct GetSock {
1254 socks: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
1255 bitmask: u32,
1256}
1257
1258impl GetSock {
1259 fn new(
1260 socks: [c_ares_sys::ares_socket_t; c_ares_sys::ARES_GETSOCK_MAXNUM],
1261 bitmask: u32,
1262 ) -> Self {
1263 GetSock { socks, bitmask }
1264 }
1265
1266 pub fn iter(&self) -> GetSockIter {
1268 GetSockIter {
1269 next: 0,
1270 getsock: self,
1271 }
1272 }
1273}
1274
1275#[derive(Clone, Copy, Debug)]
1279pub struct GetSockIter<'a> {
1280 next: usize,
1281 getsock: &'a GetSock,
1282}
1283
1284impl Iterator for GetSockIter<'_> {
1285 type Item = (Socket, bool, bool);
1286 fn next(&mut self) -> Option<Self::Item> {
1287 let index = self.next;
1288 self.next += 1;
1289 if index >= c_ares_sys::ARES_GETSOCK_MAXNUM {
1290 None
1291 } else {
1292 let bit = 1 << index;
1293 let readable = (self.getsock.bitmask & bit) != 0;
1294 let bit = bit << c_ares_sys::ARES_GETSOCK_MAXNUM;
1295 let writable = (self.getsock.bitmask & bit) != 0;
1296 if readable || writable {
1297 let fd = self.getsock.socks[index];
1298 Some((fd, readable, writable))
1299 } else {
1300 None
1301 }
1302 }
1303 }
1304}
1305
1306impl<'a> IntoIterator for &'a GetSock {
1307 type Item = (Socket, bool, bool);
1308 type IntoIter = GetSockIter<'a>;
1309
1310 fn into_iter(self) -> Self::IntoIter {
1311 self.iter()
1312 }
1313}