c_ares/
cname.rs

1use std::fmt;
2use std::os::raw::{c_int, c_uchar, c_void};
3use std::ptr;
4use std::slice;
5
6use crate::error::{Error, Result};
7use crate::hostent::{HasHostent, HostAliasResultsIter, HostentOwned};
8use crate::panic;
9
10/// The result of a successful CNAME lookup.
11#[derive(Debug)]
12pub struct CNameResults {
13    hostent: HostentOwned,
14}
15
16impl CNameResults {
17    /// Obtain a `CNameResults` from the response to a CNAME lookup.
18    pub fn parse_from(data: &[u8]) -> Result<CNameResults> {
19        let mut hostent: *mut c_types::hostent = ptr::null_mut();
20        let parse_status = unsafe {
21            c_ares_sys::ares_parse_a_reply(
22                data.as_ptr(),
23                data.len() as c_int,
24                &mut hostent,
25                ptr::null_mut(),
26                ptr::null_mut(),
27            )
28        };
29        if parse_status == c_ares_sys::ares_status_t::ARES_SUCCESS as i32 {
30            let result = CNameResults::new(hostent);
31            Ok(result)
32        } else {
33            Err(Error::from(parse_status))
34        }
35    }
36
37    fn new(hostent: *mut c_types::hostent) -> Self {
38        CNameResults {
39            hostent: HostentOwned::new(hostent),
40        }
41    }
42
43    /// Returns the hostname from this `CNameResults`.
44    pub fn hostname(&self) -> &str {
45        self.hostent.hostname()
46    }
47
48    /// Returns an iterator over the host aliases in this `CNameResults`.
49    pub fn aliases(&self) -> HostAliasResultsIter {
50        self.hostent.aliases()
51    }
52}
53
54impl fmt::Display for CNameResults {
55    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
56        self.hostent.fmt(fmt)
57    }
58}
59
60pub(crate) unsafe extern "C" fn query_cname_callback<F>(
61    arg: *mut c_void,
62    status: c_int,
63    _timeouts: c_int,
64    abuf: *mut c_uchar,
65    alen: c_int,
66) where
67    F: FnOnce(Result<CNameResults>) + Send + 'static,
68{
69    ares_callback!(
70        arg.cast::<F>(),
71        status,
72        abuf,
73        alen,
74        CNameResults::parse_from
75    );
76}