#[cfg(all(unix, any(target_os = "linux", target_os = "android")))]
extern crate nix;
#[cfg(all(unix, any(target_os = "linux", target_os = "android")))]
mod example {
extern crate c_ares;
use nix::sys::epoll::{epoll_create, epoll_ctl, epoll_wait, EpollEvent, EpollFlags, EpollOp};
use std::collections::HashSet;
use std::error::Error;
fn print_a_results(result: &c_ares::Result<c_ares::AResults>) {
match *result {
Err(ref e) => {
println!("A lookup failed with error '{}'", e.description());
}
Ok(ref a_results) => {
println!("Successful A lookup...");
for a_result in a_results {
println!("IPv4: {}", a_result.ipv4());
println!("TTL: {}", a_result.ttl());
}
}
}
}
fn print_aaaa_results(result: &c_ares::Result<c_ares::AAAAResults>) {
match *result {
Err(ref e) => {
println!("AAAA lookup failed with error '{}'", e.description());
}
Ok(ref aaaa_results) => {
println!("Successful AAAA lookup...");
for aaaa_result in aaaa_results {
println!("IPv6: {}", aaaa_result.ipv6());
println!("TTL: {}", aaaa_result.ttl());
}
}
}
}
fn print_srv_results(result: &c_ares::Result<c_ares::SRVResults>) {
match *result {
Err(ref e) => {
println!("SRV lookup failed with error '{}'", e.description());
}
Ok(ref srv_results) => {
println!("Successful SRV lookup...");
for srv_result in srv_results {
println!(
"host: {} (port: {}), priority: {} weight: {}",
srv_result.host().to_string_lossy(),
srv_result.port(),
srv_result.priority(),
srv_result.weight()
);
}
}
}
}
pub fn main() {
let mut options = c_ares::Options::new();
options
.set_flags(c_ares::Flags::STAYOPEN)
.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.query_a("apple.com", move |result| {
println!();
print_a_results(&result);
});
ares_channel.query_aaaa("google.com", move |result| {
println!();
print_aaaa_results(&result);
});
ares_channel.query_srv("_xmpp-server._tcp.gmail.com", move |result| {
println!();
print_srv_results(&result);
});
let epoll = epoll_create().expect("Failed to create epoll");
let mut tracked_fds = HashSet::<c_ares::Socket>::new();
loop {
let mut active = false;
for (fd, readable, writable) in &ares_channel.get_sock() {
let mut interest = EpollFlags::empty();
if readable {
interest |= EpollFlags::EPOLLIN;
}
if writable {
interest |= EpollFlags::EPOLLOUT;
}
let mut event = EpollEvent::new(interest, fd as u64);
let op = if tracked_fds.insert(fd) {
EpollOp::EpollCtlAdd
} else {
EpollOp::EpollCtlMod
};
epoll_ctl(epoll, op, fd, &mut event).expect("epoll_ctl failed");
active = true;
}
if !active {
break;
}
let empty_event = EpollEvent::new(EpollFlags::empty(), 0);
let mut events = [empty_event; 2];
let results = epoll_wait(epoll, &mut events, 500).expect("epoll_wait failed");
match results {
0 => {
ares_channel.process_fd(c_ares::SOCKET_BAD, c_ares::SOCKET_BAD);
}
n => {
for event in &events[0..n] {
let active_fd = event.data() as c_ares::Socket;
let rfd = if (event.events() & EpollFlags::EPOLLIN).is_empty() {
c_ares::SOCKET_BAD
} else {
active_fd
};
let wfd = if (event.events() & EpollFlags::EPOLLOUT).is_empty() {
c_ares::SOCKET_BAD
} else {
active_fd
};
ares_channel.process_fd(rfd, wfd);
}
}
}
}
}
}
#[cfg(all(unix, any(target_os = "linux", target_os = "android")))]
pub fn main() {
example::main();
}
#[cfg(not(all(unix, any(target_os = "linux", target_os = "android"))))]
pub fn main() {
println!("this example is not supported on this platform");
}