Finish implementation of gethostbyname
This commit is contained in:
parent
9978bfd783
commit
571aa90d6a
8 changed files with 105 additions and 82 deletions
|
@ -6,17 +6,12 @@ include!(concat!(
|
|||
"/src/policy_checker/dbus.rs"
|
||||
));
|
||||
|
||||
use {
|
||||
event_listener::{Event, EventListener},
|
||||
nix::unistd::Uid,
|
||||
std::collections::HashMap,
|
||||
zbus::dbus_interface,
|
||||
};
|
||||
use {std::collections::HashMap, zbus::dbus_interface};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MalcontentDBusMock {
|
||||
responses: HashMap<Uid, Vec<Restrictions>>,
|
||||
invocations_left: usize,
|
||||
finished: Event,
|
||||
}
|
||||
|
||||
#[dbus_interface(name = "com.endlessm.ParentalControls.Dns")]
|
||||
|
@ -33,17 +28,23 @@ impl MalcontentDBusMock {
|
|||
"MockError: DBus mock is saturated for user with id {}",
|
||||
user_id
|
||||
));
|
||||
|
||||
self.invocations_left -= 1;
|
||||
if self.invocations_left == 0 {
|
||||
self.finished.notify(1);
|
||||
}
|
||||
restrictions
|
||||
}
|
||||
}
|
||||
|
||||
impl MalcontentDBusMock {
|
||||
pub fn new(mut responses: HashMap<Uid, Vec<Restrictions>>) -> Self {
|
||||
let responses_size: usize = responses.values().map(|v| v.len()).sum();
|
||||
let responses_size: usize = responses
|
||||
.values()
|
||||
.map(|v| {
|
||||
std::cmp::max(
|
||||
v.len(),
|
||||
1, /* 'No restrictions' still counts as one message */
|
||||
)
|
||||
})
|
||||
.sum();
|
||||
for r in responses.values_mut() {
|
||||
r.reverse(); // we pop responses from the back, so...
|
||||
}
|
||||
|
@ -51,19 +52,10 @@ impl MalcontentDBusMock {
|
|||
let ret = Self {
|
||||
responses,
|
||||
invocations_left: responses_size,
|
||||
finished: Event::new(),
|
||||
};
|
||||
|
||||
if ret.invocations_left == 0 {
|
||||
ret.finished.notify(1);
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn waiter(&self) -> EventListener {
|
||||
self.finished.listen()
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for MalcontentDBusMock {
|
||||
|
@ -73,8 +65,6 @@ impl Drop for MalcontentDBusMock {
|
|||
"MockError: During teardown, {} invocations are still left on the mock object",
|
||||
self.invocations_left
|
||||
);
|
||||
|
||||
self.finished.notify(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,8 @@ static SETUP: Once = Once::new();
|
|||
|
||||
pub fn setup() -> Result<()> {
|
||||
SETUP.call_once(|| {
|
||||
env_logger::init();
|
||||
|
||||
let nss_config_status = unsafe {
|
||||
let db = CString::new("hosts").unwrap();
|
||||
let resolvers = CString::new("malcontent dns").unwrap();
|
||||
|
@ -130,7 +132,7 @@ pub fn resolve_with_system(family: libc::c_int, host: &str) -> Result<IpAddr> {
|
|||
Ok(IpAddr::from_str(&addr_string)?)
|
||||
}
|
||||
|
||||
pub fn resolve_with_module(family: libc::c_int, hostname: &str) -> Result<IpAddr> {
|
||||
pub fn resolve_with_module(family: libc::c_int, hostname: &str) -> Result<Vec<IpAddr>> {
|
||||
assert!(
|
||||
SETUP.is_completed(),
|
||||
"Forgot to call common::setup() at beginning of test?"
|
||||
|
@ -159,20 +161,33 @@ pub fn resolve_with_module(family: libc::c_int, hostname: &str) -> Result<IpAddr
|
|||
hostname,
|
||||
error.to_str().unwrap()
|
||||
);
|
||||
let addr_storage = SockaddrStorage::from_raw((*addr).ai_addr, Some((*addr).ai_addrlen))
|
||||
.ok_or(anyhow!("Garbled addrinfo from getaddrinfo()"))?;
|
||||
let ip = convert_addrinfo(&addr_storage)?;
|
||||
|
||||
let ips = convert_addrinfo(addr)?;
|
||||
freeaddrinfo(addr);
|
||||
Ok(ip)
|
||||
Ok(ips)
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_addrinfo(sa: &SockaddrStorage) -> Result<IpAddr> {
|
||||
if let Some(addr) = sa.as_sockaddr_in() {
|
||||
Ok(IpAddr::V4(Ipv4Addr::from(addr.ip())))
|
||||
} else if let Some(addr) = sa.as_sockaddr_in6() {
|
||||
Ok(IpAddr::V6(Ipv6Addr::from(addr.ip())))
|
||||
} else {
|
||||
bail!("addrinfo is not either an IPv4 or IPv6 address")
|
||||
unsafe fn convert_addrinfo(addrs: *const libc::addrinfo) -> Result<Vec<IpAddr>> {
|
||||
let mut ips = vec![];
|
||||
|
||||
let mut addr = addrs;
|
||||
while addr != std::ptr::null() {
|
||||
let addr_storage = SockaddrStorage::from_raw((*addr).ai_addr, Some((*addr).ai_addrlen))
|
||||
.ok_or(anyhow!("Garbled addrinfo from getaddrinfo()"))?;
|
||||
|
||||
if let Some(addr) = addr_storage.as_sockaddr_in() {
|
||||
ips.push(IpAddr::V4(Ipv4Addr::from(addr.ip())));
|
||||
} else if let Some(addr) = addr_storage.as_sockaddr_in6() {
|
||||
ips.push(IpAddr::V6(Ipv6Addr::from(addr.ip())));
|
||||
} else {
|
||||
bail!("addrinfo is not either an IPv4 or IPv6 address")
|
||||
}
|
||||
|
||||
addr = (*addr).ai_next;
|
||||
}
|
||||
|
||||
ips.sort();
|
||||
ips.dedup();
|
||||
Ok(ips)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue