#[cfg(unix)]
mod example {
extern crate c_ares;
extern crate mio;
use std::collections::HashSet;
use std::error::Error;
use std::net::IpAddr;
use std::time::Duration;
fn print_host_results(result: &c_ares::Result<c_ares::HostResults>) {
match *result {
Err(ref e) => {
println!("Host lookup failed with error '{}'", e.description());
}
Ok(host_results) => {
println!("Successful host lookup...");
println!("Hostname: {}", host_results.hostname().to_string_lossy());
for alias in host_results.aliases() {
println!("Alias: {}", alias.to_string_lossy());
}
for address in host_results.addresses() {
match address {
IpAddr::V4(v4) => println!("IPv4: {}", v4),
IpAddr::V6(v6) => println!("IPv6: {}", v6),
}
}
}
}
}
pub fn main() {
let mut options = c_ares::Options::new();
options
.set_flags(c_ares::Flags::STAYOPEN | c_ares::Flags::EDNS)
.set_timeout(500)
.set_tries(3);
let mut ares_channel =
c_ares::Channel::with_options(options).expect("Failed to create channel");
ares_channel
.set_servers(&["8.8.8.8"])
.expect("Failed to set servers");
ares_channel.get_host_by_name("google.com", c_ares::AddressFamily::INET, move |result| {
println!();
print_host_results(&result);
});
let ipv4 = "216.58.212.78".parse::<IpAddr>().unwrap();
ares_channel.get_host_by_address(&ipv4, move |results| {
println!();
print_host_results(&results);
});
let ipv6 = "2001:4860:4860::8888".parse::<IpAddr>().unwrap();
ares_channel.get_host_by_address(&ipv6, move |results| {
println!();
print_host_results(&results);
});
let poll = mio::Poll::new().expect("Failed to create poll");
let mut events = mio::Events::with_capacity(16);
let mut tracked_fds = HashSet::<c_ares::Socket>::new();
loop {
let mut new_fds = HashSet::<c_ares::Socket>::new();
for (fd, readable, writable) in &ares_channel.get_sock() {
new_fds.insert(fd);
let efd = mio::unix::EventedFd(&fd);
let token = mio::Token(fd as usize);
let mut interest = mio::Ready::empty();
if readable {
interest.insert(mio::Ready::readable())
}
if writable {
interest.insert(mio::Ready::writable())
}
let register_result = if tracked_fds.contains(&fd) {
poll.reregister(&efd, token, interest, mio::PollOpt::level())
} else {
poll.register(&efd, token, interest, mio::PollOpt::level())
};
register_result.expect("failed to register interest");
}
let unwanted = &tracked_fds - &new_fds;
for fd in &unwanted {
let efd = mio::unix::EventedFd(fd);
poll.deregister(&efd)
.expect("failed to deregister interest");
}
tracked_fds = new_fds;
if tracked_fds.is_empty() {
break;
}
let timeout = Duration::from_millis(100);
let results = poll.poll(&mut events, Some(timeout)).expect("poll failed");
match results {
0 => {
ares_channel.process_fd(c_ares::SOCKET_BAD, c_ares::SOCKET_BAD);
}
_ => {
for event in &events {
let mio::Token(active_fd) = event.token();
let rfd = if event.readiness().is_readable() {
active_fd as c_ares::Socket
} else {
c_ares::SOCKET_BAD
};
let wfd = if event.readiness().is_writable() {
active_fd as c_ares::Socket
} else {
c_ares::SOCKET_BAD
};
ares_channel.process_fd(rfd, wfd);
}
}
}
}
}
}
#[cfg(unix)]
pub fn main() {
example::main();
}
#[cfg(not(unix))]
pub fn main() {
println!("this example is not supported on this platform");
}