Skip to content

Commit

Permalink
add a test case for refresh PTR
Browse files Browse the repository at this point in the history
  • Loading branch information
keepsimple1 committed May 14, 2024
1 parent 0d13c16 commit 1e4bff0
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 9 deletions.
91 changes: 82 additions & 9 deletions src/service_daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,9 @@ enum Counter {
Browse,
ResolveHostname,
Respond,
CacheRefreshQuery,
CacheRefreshPTR,
CacheRefreshSRV,
CacheRefreshAddr,
}

impl fmt::Display for Counter {
Expand All @@ -119,7 +121,9 @@ impl fmt::Display for Counter {
Self::Browse => write!(f, "browse"),
Self::ResolveHostname => write!(f, "resolve-hostname"),
Self::Respond => write!(f, "respond"),
Self::CacheRefreshQuery => write!(f, "cache-refresh"),
Self::CacheRefreshPTR => write!(f, "cache-refresh-ptr"),
Self::CacheRefreshSRV => write!(f, "cache-refresh-srv"),
Self::CacheRefreshAddr => write!(f, "cache-refresh-addr"),
}
}
}
Expand Down Expand Up @@ -552,9 +556,10 @@ impl ServiceDaemon {
}

// Refresh cached service records with active queriers
let mut query_count = zc.refresh_active_services();
zc.refresh_active_services();

// Refresh cached A/AAAA records with active queriers
let mut query_count = 0;
for (hostname, _sender) in zc.hostname_resolvers.iter() {
for (hostname, ip_addr) in
zc.cache.refresh_due_hostname_resolutions(hostname).iter()
Expand All @@ -564,7 +569,7 @@ impl ServiceDaemon {
}
}

zc.increase_counter(Counter::CacheRefreshQuery, query_count);
zc.increase_counter(Counter::CacheRefreshAddr, query_count);

// check and evict expired records in our cache
let now = current_time_millis();
Expand Down Expand Up @@ -2181,24 +2186,25 @@ impl Zeroconf {
}

/// Refresh cached service records with active queriers
fn refresh_active_services(&mut self) -> i64 {
let mut query_count = 0;
fn refresh_active_services(&mut self) {
let mut query_ptr_count = 0;
let mut query_srv_count = 0;
let mut new_timers = HashSet::new();

for (ty_domain, _sender) in self.service_queriers.iter() {
let refreshed_timers = self.cache.refresh_due_ptr(ty_domain);
if !refreshed_timers.is_empty() {
debug!("sending refresh query for PTR: {}", ty_domain);
self.send_query(ty_domain, TYPE_PTR);
query_count += 1;
query_ptr_count += 1;
new_timers.extend(refreshed_timers);
}

let (instances, timers) = self.cache.refresh_due_srv(ty_domain);
for instance in instances.iter() {
debug!("sending refresh query for SRV: {}", instance);
self.send_query(instance, TYPE_ANY);
query_count += 1;
query_srv_count += 1;
}
new_timers.extend(timers);
}
Expand All @@ -2207,7 +2213,8 @@ impl Zeroconf {
self.add_timer(timer);
}

query_count
self.increase_counter(Counter::CacheRefreshPTR, query_ptr_count);
self.increase_counter(Counter::CacheRefreshSRV, query_srv_count);
}
}

Expand Down Expand Up @@ -3340,4 +3347,70 @@ mod tests {

client.shutdown().unwrap();
}

#[test]
fn test_refresh_ptr() {
// construct service info
let service_type = "_refresh-ptr._udp.local.";
let instance = "test_instance";
let host_name = "refresh_ptr_host.local.";
let service_ip_addr = my_ip_interfaces()
.iter()
.find(|iface| iface.ip().is_ipv4())
.map(|iface| iface.ip())
.unwrap();

let mut my_service = ServiceInfo::new(
service_type,
instance,
host_name,
&service_ip_addr,
5023,
None,
)
.unwrap();

let new_ttl = 2; // for testing only.
my_service._set_other_ttl(new_ttl);

// register my service
let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
let result = mdns_server.register(my_service);
assert!(result.is_ok());

let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
let browse_chan = mdns_client.browse(service_type).unwrap();
let timeout = Duration::from_secs(1);
let mut resolved = false;

// resolve the service first.
while let Ok(event) = browse_chan.recv_timeout(timeout) {
match event {
ServiceEvent::ServiceResolved(info) => {
resolved = true;
println!("Resolved a service of {}", &info.get_fullname());
break;
}
_ => {}
}
}

assert!(resolved);

// wait over 80% of TTL, and refresh PTR should be sent out.
let timeout = Duration::from_millis(1800);
while let Ok(event) = browse_chan.recv_timeout(timeout) {
println!("event: {:?}", &event);
}

// verify refresh counter.
let metrics_chan = mdns_client.get_metrics().unwrap();
let metrics = metrics_chan.recv_timeout(timeout).unwrap();
let refresh_counter = metrics["cache-refresh-ptr"];
assert_eq!(refresh_counter, 1);

// Exit the server so that no more responses.
mdns_server.shutdown().unwrap();
mdns_client.shutdown().unwrap();
}
}
5 changes: 5 additions & 0 deletions src/service_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,11 @@ impl ServiceInfo {
pub(crate) fn _set_host_ttl(&mut self, ttl: u32) {
self.host_ttl = ttl;
}

/// other_ttl is for PTR and TXT records.
pub(crate) fn _set_other_ttl(&mut self, ttl: u32) {
self.other_ttl = ttl;
}
}

/// Removes potentially duplicated ".local." at the end of "hostname".
Expand Down

0 comments on commit 1e4bff0

Please sign in to comment.