use std::net::{IpAddr, Ipv4Addr};
use std::sync::Arc;
use arcbox_dns::LocalHostsTable;
use arcbox_net::dns::{DnsConfig, DnsForwarder};
fn build_query(name: &str) -> Vec<u8> {
let mut pkt = vec![0xAB, 0xCD, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00];
pkt.extend_from_slice(&[0x00, 0x00, 0x00, 0x00]);
for label in name.split('.') {
pkt.push(label.len() as u8);
pkt.extend_from_slice(label.as_bytes());
}
pkt.push(0x00);
pkt.extend_from_slice(&[0x00, 0x01, 0x00, 0x01]); pkt
}
#[test]
fn shared_table_visible_to_both_forwarders() {
let shared = Arc::new(LocalHostsTable::new(Default::default()));
let config1 = DnsConfig::default();
let config2 = DnsConfig::default();
let forwarder1 = DnsForwarder::with_shared_hosts(config1, Arc::clone(&shared));
let forwarder2 = DnsForwarder::with_shared_hosts(config2, Arc::clone(&shared));
let ip = IpAddr::V4(Ipv4Addr::new(172, 17, 0, 2));
forwarder1.add_local_host("my-nginx", ip);
assert_eq!(forwarder1.resolve_local("my-nginx"), Some(ip));
assert_eq!(forwarder2.resolve_local("my-nginx"), Some(ip));
assert_eq!(forwarder1.resolve_local("my-nginx.arcbox.local"), Some(ip));
assert_eq!(forwarder2.resolve_local("my-nginx.arcbox.local"), Some(ip));
let query = build_query("my-nginx.arcbox.local");
let resp = forwarder2.try_resolve_locally(&query);
assert!(
resp.is_some(),
"VMM forwarder should resolve from shared table"
);
let query = build_query("missing.arcbox.local");
let resp = forwarder2.try_resolve_locally_or_nxdomain(&query);
assert!(resp.is_some());
let r = resp.unwrap();
assert_eq!(r[3] & 0x0F, 3, "should be NXDOMAIN");
forwarder1.remove_local_host("my-nginx");
assert_eq!(forwarder1.resolve_local("my-nginx"), None);
assert_eq!(forwarder2.resolve_local("my-nginx"), None);
}
#[test]
fn separate_tables_are_independent() {
let config1 = DnsConfig::default();
let config2 = DnsConfig::default();
let f1 = DnsForwarder::new(config1);
let f2 = DnsForwarder::new(config2);
let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1));
f1.add_local_host("only-in-f1", ip);
assert_eq!(f1.resolve_local("only-in-f1"), Some(ip));
assert_eq!(f2.resolve_local("only-in-f1"), None);
}