1#[cfg(feature = "logging")]
32use crate::log::{debug, error, trace};
33use crate::{
34 current_time_millis,
35 dns_cache::{DnsCache, IpType},
36 dns_parser::{
37 ip_address_rr_type, DnsAddress, DnsEntryExt, DnsIncoming, DnsOutgoing, DnsPointer,
38 DnsRecordBox, DnsRecordExt, DnsSrv, DnsTxt, InterfaceId, RRType, ScopedIp,
39 CLASS_CACHE_FLUSH, CLASS_IN, FLAGS_AA, FLAGS_QR_QUERY, FLAGS_QR_RESPONSE, MAX_MSG_ABSOLUTE,
40 },
41 error::{e_fmt, Error, Result},
42 service_info::{
43 valid_ip_on_intf, DnsRegistry, MyIntf, Probe, ServiceInfo, ServiceStatus,
44 MULTICAST_RATE_LIMIT_MILLIS,
45 },
46 Receiver, ResolvedService, TxtProperties,
47};
48use flume::{bounded, Sender, TrySendError};
49use if_addrs::{IfAddr, Interface};
50use mio::{event::Source, net::UdpSocket as MioUdpSocket, Interest, Poll, Registry, Token};
51use socket2::Domain;
52use socket_pktinfo::PktInfoUdpSocket;
53use std::{
54 cmp::{self, Reverse},
55 collections::{hash_map::Entry, BinaryHeap, HashMap, HashSet},
56 fmt, io,
57 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket},
58 str, thread,
59 time::Duration,
60 vec,
61};
62
63pub const SERVICE_NAME_LEN_MAX_DEFAULT: u8 = 15;
67
68pub const IP_CHECK_INTERVAL_IN_SECS_DEFAULT: u32 = 5;
70
71pub const VERIFY_TIMEOUT_DEFAULT: Duration = Duration::from_secs(10);
74
75pub const MDNS_PORT: u16 = 5353;
77
78const GROUP_ADDR_V4: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251);
79const GROUP_ADDR_V6: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0xfb);
80const LOOPBACK_V4: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
81
82const RESOLVE_WAIT_IN_MILLIS: u64 = 500;
83
84const ANNOUNCE_SECOND_DELAY_MILLIS: u64 = MULTICAST_RATE_LIMIT_MILLIS + 100;
92
93const ANNOUNCE_SECOND_JITTER_MILLIS: u64 = 50;
96
97#[allow(clippy::assertions_on_constants)]
101const _: () = assert!(ANNOUNCE_SECOND_DELAY_MILLIS > MULTICAST_RATE_LIMIT_MILLIS);
102
103const SHARED_RESPONSE_DELAY_MIN_MILLIS: u64 = 10;
111
112const SHARED_RESPONSE_DELAY_MAX_MILLIS: u64 = 50;
114
115const INITIAL_QUERY_DELAY_MIN_MILLIS: u64 = 10;
123const INITIAL_QUERY_DELAY_MAX_MILLIS: u64 = 50;
124
125#[derive(Debug)]
127pub enum UnregisterStatus {
128 OK,
130 NotFound,
132}
133
134#[derive(Debug, PartialEq, Clone, Eq)]
136#[non_exhaustive]
137pub enum DaemonStatus {
138 Running,
140
141 Shutdown,
143}
144
145#[derive(Hash, Eq, PartialEq)]
148enum Counter {
149 Register,
150 RegisterResend,
151 Unregister,
152 UnregisterResend,
153 Browse,
154 ResolveHostname,
155 Respond,
156 CacheRefreshPTR,
157 CacheRefreshSrvTxt,
158 CacheRefreshAddr,
159 KnownAnswerSuppression,
160 CachedPTR,
161 CachedSRV,
162 CachedAddr,
163 CachedTxt,
164 CachedNSec,
165 CachedSubtype,
166 DnsRegistryProbe,
167 DnsRegistryActive,
168 DnsRegistryTimer,
169 DnsRegistryNameChange,
170 Timer,
171}
172
173impl fmt::Display for Counter {
174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175 match self {
176 Self::Register => write!(f, "register"),
177 Self::RegisterResend => write!(f, "register-resend"),
178 Self::Unregister => write!(f, "unregister"),
179 Self::UnregisterResend => write!(f, "unregister-resend"),
180 Self::Browse => write!(f, "browse"),
181 Self::ResolveHostname => write!(f, "resolve-hostname"),
182 Self::Respond => write!(f, "respond"),
183 Self::CacheRefreshPTR => write!(f, "cache-refresh-ptr"),
184 Self::CacheRefreshSrvTxt => write!(f, "cache-refresh-srv-txt"),
185 Self::CacheRefreshAddr => write!(f, "cache-refresh-addr"),
186 Self::KnownAnswerSuppression => write!(f, "known-answer-suppression"),
187 Self::CachedPTR => write!(f, "cached-ptr"),
188 Self::CachedSRV => write!(f, "cached-srv"),
189 Self::CachedAddr => write!(f, "cached-addr"),
190 Self::CachedTxt => write!(f, "cached-txt"),
191 Self::CachedNSec => write!(f, "cached-nsec"),
192 Self::CachedSubtype => write!(f, "cached-subtype"),
193 Self::DnsRegistryProbe => write!(f, "dns-registry-probe"),
194 Self::DnsRegistryActive => write!(f, "dns-registry-active"),
195 Self::DnsRegistryTimer => write!(f, "dns-registry-timer"),
196 Self::DnsRegistryNameChange => write!(f, "dns-registry-name-change"),
197 Self::Timer => write!(f, "timer"),
198 }
199 }
200}
201
202#[derive(Debug)]
203enum InternalError {
204 IntfAddrInvalid(Interface),
205}
206
207impl fmt::Display for InternalError {
208 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209 match self {
210 InternalError::IntfAddrInvalid(iface) => write!(f, "interface addr invalid: {iface:?}"),
211 }
212 }
213}
214
215type MyResult<T> = core::result::Result<T, InternalError>;
216
217struct MyUdpSocket {
222 pktinfo: PktInfoUdpSocket,
225
226 mio: MioUdpSocket,
229}
230
231impl MyUdpSocket {
232 pub fn new(pktinfo: PktInfoUdpSocket) -> io::Result<Self> {
233 let std_sock = pktinfo.try_clone_std()?;
234 let mio = MioUdpSocket::from_std(std_sock);
235
236 Ok(Self { pktinfo, mio })
237 }
238}
239
240impl Source for MyUdpSocket {
242 fn register(
243 &mut self,
244 registry: &Registry,
245 token: Token,
246 interests: Interest,
247 ) -> io::Result<()> {
248 self.mio.register(registry, token, interests)
249 }
250
251 fn reregister(
252 &mut self,
253 registry: &Registry,
254 token: Token,
255 interests: Interest,
256 ) -> io::Result<()> {
257 self.mio.reregister(registry, token, interests)
258 }
259
260 fn deregister(&mut self, registry: &Registry) -> std::io::Result<()> {
261 self.mio.deregister(registry)
262 }
263}
264
265pub type Metrics = HashMap<String, i64>;
268
269const IPV4_SOCK_EVENT_KEY: usize = 4; const IPV6_SOCK_EVENT_KEY: usize = 6; const SIGNAL_SOCK_EVENT_KEY: usize = usize::MAX - 1; #[derive(Clone)]
277pub struct ServiceDaemon {
278 sender: Sender<Command>,
280
281 signal_addr: SocketAddr,
287}
288
289impl ServiceDaemon {
290 pub fn new() -> Result<Self> {
306 Self::new_with_port(MDNS_PORT)
307 }
308
309 pub fn new_with_port(port: u16) -> Result<Self> {
341 let signal_addr = SocketAddrV4::new(LOOPBACK_V4, 0);
344
345 let signal_sock = UdpSocket::bind(signal_addr)
346 .map_err(|e| e_fmt!("failed to create signal_sock for daemon: {}", e))?;
347
348 let signal_addr = signal_sock
350 .local_addr()
351 .map_err(|e| e_fmt!("failed to get signal sock addr: {}", e))?;
352
353 signal_sock
355 .set_nonblocking(true)
356 .map_err(|e| e_fmt!("failed to set nonblocking for signal socket: {}", e))?;
357
358 let poller = Poll::new().map_err(|e| e_fmt!("failed to create mio Poll: {e}"))?;
359
360 let (sender, receiver) = bounded(100);
361
362 let mio_sock = MioUdpSocket::from_std(signal_sock);
364 let cmd_sender = sender.clone();
365 thread::Builder::new()
366 .name("mDNS_daemon".to_string())
367 .spawn(move || {
368 Self::daemon_thread(mio_sock, poller, receiver, port, cmd_sender, signal_addr)
369 })
370 .map_err(|e| e_fmt!("thread builder failed to spawn: {}", e))?;
371
372 Ok(Self {
373 sender,
374 signal_addr,
375 })
376 }
377
378 fn send_cmd(&self, cmd: Command) -> Result<()> {
381 let cmd_name = cmd.to_string();
382
383 self.sender.try_send(cmd).map_err(|e| match e {
385 TrySendError::Full(_) => Error::Again,
386 TrySendError::Disconnected(_) => Error::DaemonShutdown,
387 })?;
388
389 let addr = SocketAddrV4::new(LOOPBACK_V4, 0);
391 let socket = UdpSocket::bind(addr)
392 .map_err(|e| e_fmt!("Failed to create socket to send signal: {}", e))?;
393 socket
394 .send_to(cmd_name.as_bytes(), self.signal_addr)
395 .map_err(|e| {
396 e_fmt!(
397 "signal socket send_to {} ({}) failed: {}",
398 self.signal_addr,
399 cmd_name,
400 e
401 )
402 })?;
403
404 Ok(())
405 }
406
407 pub fn browse(&self, service_type: &str) -> Result<Receiver<ServiceEvent>> {
427 check_domain_suffix(service_type)?;
428
429 let (resp_s, resp_r) = bounded(10);
430 self.send_cmd(Command::Browse(service_type.to_string(), 1, false, resp_s))?;
431 Ok(resp_r)
432 }
433
434 pub fn browse_cache(&self, service_type: &str) -> Result<Receiver<ServiceEvent>> {
447 check_domain_suffix(service_type)?;
448
449 let (resp_s, resp_r) = bounded(10);
450 self.send_cmd(Command::Browse(service_type.to_string(), 1, true, resp_s))?;
451 Ok(resp_r)
452 }
453
454 pub fn stop_browse(&self, ty_domain: &str) -> Result<()> {
462 self.send_cmd(Command::StopBrowse(ty_domain.to_string()))
463 }
464
465 pub fn resolve_hostname(
485 &self,
486 hostname: &str,
487 timeout: Option<u64>,
488 ) -> Result<Receiver<HostnameResolutionEvent>> {
489 check_hostname(hostname)?;
490 let (resp_s, resp_r) = bounded(10);
491 self.send_cmd(Command::ResolveHostname(
492 hostname.to_string(),
493 1,
494 resp_s,
495 timeout,
496 ))?;
497 Ok(resp_r)
498 }
499
500 pub fn stop_resolve_hostname(&self, hostname: &str) -> Result<()> {
506 self.send_cmd(Command::StopResolveHostname(hostname.to_string()))
507 }
508
509 pub fn register(&self, service_info: ServiceInfo) -> Result<()> {
529 check_service_name(service_info.get_fullname())?;
530 check_hostname(service_info.get_hostname())?;
531
532 self.send_cmd(Command::Register(service_info.into()))
533 }
534
535 pub fn unregister(&self, fullname: &str) -> Result<Receiver<UnregisterStatus>> {
546 let (resp_s, resp_r) = bounded(1);
547 self.send_cmd(Command::Unregister(fullname.to_lowercase(), resp_s))?;
548 Ok(resp_r)
549 }
550
551 pub fn monitor(&self) -> Result<Receiver<DaemonEvent>> {
561 let (resp_s, resp_r) = bounded(100);
562 self.send_cmd(Command::Monitor(resp_s))?;
563 Ok(resp_r)
564 }
565
566 pub fn shutdown(&self) -> Result<Receiver<DaemonStatus>> {
574 let (resp_s, resp_r) = bounded(1);
575 self.send_cmd(Command::Exit(resp_s))?;
576 Ok(resp_r)
577 }
578
579 pub fn status(&self) -> Result<Receiver<DaemonStatus>> {
587 let (resp_s, resp_r) = bounded(1);
588
589 if self.sender.is_disconnected() {
590 resp_s
591 .send(DaemonStatus::Shutdown)
592 .map_err(|e| e_fmt!("failed to send daemon status to the client: {}", e))?;
593 } else {
594 self.send_cmd(Command::GetStatus(resp_s))?;
595 }
596
597 Ok(resp_r)
598 }
599
600 pub fn get_metrics(&self) -> Result<Receiver<Metrics>> {
611 let (resp_s, resp_r) = bounded(1);
612 self.send_cmd(Command::GetMetrics(resp_s))?;
613 Ok(resp_r)
614 }
615
616 pub fn set_service_name_len_max(&self, len_max: u8) -> Result<()> {
631 const SERVICE_NAME_LEN_MAX_LIMIT: u8 = 30; if len_max > SERVICE_NAME_LEN_MAX_LIMIT {
634 return Err(Error::Msg(format!(
635 "service name length max {len_max} is too large"
636 )));
637 }
638
639 self.send_cmd(Command::SetOption(DaemonOption::ServiceNameLenMax(len_max)))
640 }
641
642 pub fn set_ip_check_interval(&self, interval_in_secs: u32) -> Result<()> {
648 let interval_in_millis = interval_in_secs as u64 * 1000;
649 self.send_cmd(Command::SetOption(DaemonOption::IpCheckInterval(
650 interval_in_millis,
651 )))
652 }
653
654 pub fn get_ip_check_interval(&self) -> Result<u32> {
656 let (resp_s, resp_r) = bounded(1);
657 self.send_cmd(Command::GetOption(resp_s))?;
658
659 let option = resp_r
660 .recv_timeout(Duration::from_secs(10))
661 .map_err(|e| e_fmt!("failed to receive ip check interval: {}", e))?;
662 let ip_check_interval_in_secs = option.ip_check_interval / 1000;
663 Ok(ip_check_interval_in_secs as u32)
664 }
665
666 pub fn enable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()> {
673 let if_kind_vec = if_kind.into_vec();
674 self.send_cmd(Command::SetOption(DaemonOption::EnableInterface(
675 if_kind_vec.kinds,
676 )))
677 }
678
679 pub fn disable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()> {
686 let if_kind_vec = if_kind.into_vec();
687 self.send_cmd(Command::SetOption(DaemonOption::DisableInterface(
688 if_kind_vec.kinds,
689 )))
690 }
691
692 pub fn accept_unsolicited(&self, accept: bool) -> Result<()> {
703 self.send_cmd(Command::SetOption(DaemonOption::AcceptUnsolicited(accept)))
704 }
705
706 pub fn include_apple_p2p(&self, include: bool) -> Result<()> {
709 self.send_cmd(Command::SetOption(DaemonOption::IncludeAppleP2P(include)))
710 }
711
712 #[cfg(test)]
713 pub fn test_down_interface(&self, ifname: &str) -> Result<()> {
714 self.send_cmd(Command::SetOption(DaemonOption::TestDownInterface(
715 ifname.to_string(),
716 )))
717 }
718
719 #[cfg(test)]
720 pub fn test_up_interface(&self, ifname: &str) -> Result<()> {
721 self.send_cmd(Command::SetOption(DaemonOption::TestUpInterface(
722 ifname.to_string(),
723 )))
724 }
725
726 pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()> {
742 self.send_cmd(Command::SetOption(DaemonOption::MulticastLoopV4(on)))
743 }
744
745 pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()> {
761 self.send_cmd(Command::SetOption(DaemonOption::MulticastLoopV6(on)))
762 }
763
764 pub fn verify(&self, instance_fullname: String, timeout: Duration) -> Result<()> {
783 self.send_cmd(Command::Verify(instance_fullname, timeout))
784 }
785
786 fn daemon_thread(
787 signal_sock: MioUdpSocket,
788 poller: Poll,
789 receiver: Receiver<Command>,
790 port: u16,
791 cmd_sender: Sender<Command>,
792 signal_addr: SocketAddr,
793 ) {
794 let mut zc = Zeroconf::new(signal_sock, poller, port, cmd_sender, signal_addr);
795
796 if let Some(cmd) = zc.run(receiver) {
797 match cmd {
798 Command::Exit(resp_s) => {
799 if let Err(e) = resp_s.send(DaemonStatus::Shutdown) {
802 debug!("exit: failed to send response of shutdown: {}", e);
803 }
804 }
805 _ => {
806 debug!("Unexpected command: {:?}", cmd);
807 }
808 }
809 }
810 }
811}
812
813fn _new_socket_bind(intf: &Interface, should_loop: bool) -> Result<MyUdpSocket> {
815 let intf_ip = &intf.ip();
818 match intf_ip {
819 IpAddr::V4(ip) => {
820 let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), MDNS_PORT);
821 let sock = new_socket(addr.into(), true)?;
822
823 sock.join_multicast_v4(&GROUP_ADDR_V4, ip)
825 .map_err(|e| e_fmt!("join multicast group on addr {}: {}", intf_ip, e))?;
826
827 sock.set_multicast_if_v4(ip)
829 .map_err(|e| e_fmt!("set multicast_if on addr {}: {}", ip, e))?;
830
831 sock.set_multicast_ttl_v4(255)
836 .map_err(|e| e_fmt!("set set_multicast_ttl_v4 on addr {}: {}", ip, e))?;
837
838 if !should_loop {
839 sock.set_multicast_loop_v4(false)
840 .map_err(|e| e_fmt!("failed to set multicast loop v4 for {ip}: {e}"))?;
841 }
842
843 let multicast_addr = SocketAddrV4::new(GROUP_ADDR_V4, MDNS_PORT).into();
845 let test_packets = DnsOutgoing::new(0).to_data_on_wire();
846 for packet in test_packets {
847 sock.send_to(&packet, &multicast_addr)
848 .map_err(|e| e_fmt!("send multicast packet on addr {}: {}", ip, e))?;
849 }
850 MyUdpSocket::new(sock)
851 .map_err(|e| e_fmt!("failed to create MySocket for interface {}: {e}", intf.name))
852 }
853 IpAddr::V6(ip) => {
854 let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), MDNS_PORT, 0, 0);
855 let sock = new_socket(addr.into(), true)?;
856
857 let if_index = intf.index.unwrap_or(0);
858
859 sock.join_multicast_v6(&GROUP_ADDR_V6, if_index)
861 .map_err(|e| e_fmt!("join multicast group on addr {}: {}", ip, e))?;
862
863 sock.set_multicast_if_v6(if_index)
865 .map_err(|e| e_fmt!("set multicast_if on addr {}: {}", ip, e))?;
866
867 MyUdpSocket::new(sock)
872 .map_err(|e| e_fmt!("failed to create MySocket for interface {}: {e}", intf.name))
873 }
874 }
875}
876
877fn new_socket(addr: SocketAddr, non_block: bool) -> Result<PktInfoUdpSocket> {
880 let domain = match addr {
881 SocketAddr::V4(_) => socket2::Domain::IPV4,
882 SocketAddr::V6(_) => socket2::Domain::IPV6,
883 };
884
885 let fd = PktInfoUdpSocket::new(domain).map_err(|e| e_fmt!("create socket failed: {}", e))?;
886
887 fd.set_reuse_address(true)
888 .map_err(|e| e_fmt!("set ReuseAddr failed: {}", e))?;
889 #[cfg(unix)]
890 if let Err(e) = fd.set_reuse_port(true) {
891 debug!(
892 "SO_REUSEPORT is not supported, continuing without it: {}",
893 e
894 );
895 }
896
897 if non_block {
898 fd.set_nonblocking(true)
899 .map_err(|e| e_fmt!("set O_NONBLOCK: {}", e))?;
900 }
901
902 fd.bind(&addr.into())
903 .map_err(|e| e_fmt!("socket bind to {} failed: {}", &addr, e))?;
904
905 trace!("new socket bind to {}", &addr);
906 Ok(fd)
907}
908
909struct ReRun {
911 next_time: u64,
913 command: Command,
914}
915
916struct DelayedResponse {
918 next_time: u64,
920 out: DnsOutgoing,
921 if_index: u32,
922 is_ipv4: bool,
923}
924
925#[derive(Debug, Clone)]
929#[non_exhaustive]
930pub enum IfKind {
931 All,
933
934 IPv4,
936
937 IPv6,
939
940 Name(String),
942
943 Addr(IpAddr),
947
948 LoopbackV4,
952
953 LoopbackV6,
955
956 IndexV4(u32),
958
959 IndexV6(u32),
961
962 Predicate(IfPredicate),
964}
965
966impl IfKind {
967 pub(crate) fn matches(&self, intf: &Interface) -> bool {
969 match self {
970 Self::All => true,
971 Self::IPv4 => intf.ip().is_ipv4(),
972 Self::IPv6 => intf.ip().is_ipv6(),
973 Self::Name(ifname) => ifname == &intf.name,
974 Self::Addr(addr) => addr == &intf.ip(),
975 Self::LoopbackV4 => intf.is_loopback() && intf.ip().is_ipv4(),
976 Self::LoopbackV6 => intf.is_loopback() && intf.ip().is_ipv6(),
977 Self::IndexV4(idx) => intf.index == Some(*idx) && intf.ip().is_ipv4(),
978 Self::IndexV6(idx) => intf.index == Some(*idx) && intf.ip().is_ipv6(),
979 Self::Predicate(p) => p.matches(intf),
980 }
981 }
982}
983
984impl From<&str> for IfKind {
987 fn from(val: &str) -> Self {
988 Self::Name(val.to_string())
989 }
990}
991
992impl From<&String> for IfKind {
993 fn from(val: &String) -> Self {
994 Self::Name(val.to_string())
995 }
996}
997
998impl From<IpAddr> for IfKind {
1000 fn from(val: IpAddr) -> Self {
1001 Self::Addr(val)
1002 }
1003}
1004
1005pub struct IfKindVec {
1007 kinds: Vec<IfKind>,
1008}
1009
1010pub trait IntoIfKindVec {
1012 fn into_vec(self) -> IfKindVec;
1013}
1014
1015impl<T: Into<IfKind>> IntoIfKindVec for T {
1016 fn into_vec(self) -> IfKindVec {
1017 let if_kind: IfKind = self.into();
1018 IfKindVec {
1019 kinds: vec![if_kind],
1020 }
1021 }
1022}
1023
1024impl<T: Into<IfKind>> IntoIfKindVec for Vec<T> {
1025 fn into_vec(self) -> IfKindVec {
1026 let kinds: Vec<IfKind> = self.into_iter().map(|x| x.into()).collect();
1027 IfKindVec { kinds }
1028 }
1029}
1030
1031#[derive(Clone)]
1033pub struct IfPredicate(std::sync::Arc<dyn Fn(&Interface) -> bool + Send + Sync>);
1034
1035impl IfPredicate {
1036 pub fn new(predicate: impl Fn(&Interface) -> bool + Send + Sync + 'static) -> Self {
1047 Self(std::sync::Arc::new(predicate))
1048 }
1049
1050 pub(crate) fn matches(&self, intf: &Interface) -> bool {
1051 self.0(intf)
1052 }
1053}
1054
1055impl std::fmt::Debug for IfPredicate {
1056 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1057 write!(f, "IfPredicate(...)")
1058 }
1059}
1060
1061struct IfSelection {
1063 if_kind: IfKind,
1065
1066 selected: bool,
1068}
1069
1070struct Zeroconf {
1072 port: u16,
1075
1076 my_intfs: HashMap<u32, MyIntf>,
1078
1079 ipv4_sock: Option<MyUdpSocket>,
1081
1082 ipv6_sock: Option<MyUdpSocket>,
1084
1085 my_services: HashMap<String, ServiceInfo>,
1087
1088 cache: DnsCache,
1090
1091 dns_registry_map: HashMap<u32, DnsRegistry>,
1093
1094 service_queriers: HashMap<String, Sender<ServiceEvent>>, hostname_resolvers: HashMap<String, (Sender<HostnameResolutionEvent>, Option<u64>)>, retransmissions: Vec<ReRun>,
1105
1106 delayed_responses: Vec<DelayedResponse>,
1108
1109 counters: Metrics,
1110
1111 poller: Poll,
1113
1114 monitors: Vec<Sender<DaemonEvent>>,
1116
1117 service_name_len_max: u8,
1119
1120 ip_check_interval: u64,
1122
1123 if_selections: Vec<IfSelection>,
1125
1126 signal_sock: MioUdpSocket,
1128
1129 timers: BinaryHeap<Reverse<u64>>,
1135
1136 status: DaemonStatus,
1137
1138 pending_resolves: HashSet<String>,
1140
1141 resolved: HashSet<String>,
1143
1144 multicast_loop_v4: bool,
1145
1146 multicast_loop_v6: bool,
1147
1148 accept_unsolicited: bool,
1149
1150 include_apple_p2p: bool,
1151
1152 cmd_sender: Sender<Command>,
1153
1154 signal_addr: SocketAddr,
1155
1156 #[cfg(test)]
1157 test_down_interfaces: HashSet<String>,
1158}
1159
1160fn join_multicast_group(my_sock: &PktInfoUdpSocket, intf: &Interface) -> Result<()> {
1162 let intf_ip = &intf.ip();
1163 match intf_ip {
1164 IpAddr::V4(ip) => {
1165 debug!("join multicast group V4 on {} addr {ip}", intf.name);
1167 my_sock
1168 .join_multicast_v4(&GROUP_ADDR_V4, ip)
1169 .map_err(|e| e_fmt!("PKT join multicast group on addr {}: {}", intf_ip, e))?;
1170 }
1171 IpAddr::V6(ip) => {
1172 let if_index = intf.index.unwrap_or(0);
1173 debug!(
1175 "join multicast group V6 on {} addr {ip} with index {if_index}",
1176 intf.name
1177 );
1178 my_sock
1179 .join_multicast_v6(&GROUP_ADDR_V6, if_index)
1180 .map_err(|e| e_fmt!("PKT join multicast group on addr {}: {}", ip, e))?;
1181 }
1182 }
1183 Ok(())
1184}
1185
1186impl Zeroconf {
1187 fn new(
1188 signal_sock: MioUdpSocket,
1189 poller: Poll,
1190 port: u16,
1191 cmd_sender: Sender<Command>,
1192 signal_addr: SocketAddr,
1193 ) -> Self {
1194 let my_ifaddrs = my_ip_interfaces(true);
1196
1197 let mut my_intfs = HashMap::new();
1201 let mut dns_registry_map = HashMap::new();
1202
1203 let mut ipv4_sock = None;
1206 let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), port);
1207 match new_socket(addr.into(), true) {
1208 Ok(sock) => {
1209 sock.set_multicast_ttl_v4(255)
1214 .map_err(|e| e_fmt!("set set_multicast_ttl_v4 on addr: {}", e))
1215 .ok();
1216
1217 ipv4_sock = match MyUdpSocket::new(sock) {
1219 Ok(s) => Some(s),
1220 Err(e) => {
1221 debug!("failed to create IPv4 MyUdpSocket: {e}");
1222 None
1223 }
1224 };
1225 }
1226 Err(e) => debug!("failed to create IPv4 socket: {e}"),
1228 }
1229
1230 let mut ipv6_sock = None;
1231 let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), port, 0, 0);
1232 match new_socket(addr.into(), true) {
1233 Ok(sock) => {
1234 sock.set_multicast_hops_v6(255)
1238 .map_err(|e| e_fmt!("set set_multicast_hops_v6: {}", e))
1239 .ok();
1240
1241 ipv6_sock = match MyUdpSocket::new(sock) {
1243 Ok(s) => Some(s),
1244 Err(e) => {
1245 debug!("failed to create IPv6 MyUdpSocket: {e}");
1246 None
1247 }
1248 };
1249 }
1250 Err(e) => debug!("failed to create IPv6 socket: {e}"),
1251 }
1252
1253 for intf in my_ifaddrs {
1255 let sock_opt = if intf.ip().is_ipv4() {
1256 &ipv4_sock
1257 } else {
1258 &ipv6_sock
1259 };
1260 let Some(sock) = sock_opt else {
1261 debug!(
1262 "no socket available for interface {} with addr {}. Skipped.",
1263 intf.name,
1264 intf.ip()
1265 );
1266 continue;
1267 };
1268
1269 if let Err(e) = join_multicast_group(&sock.pktinfo, &intf) {
1270 debug!("failed to join multicast: {}: {e}. Skipped.", &intf.ip());
1271 }
1272
1273 let if_index = intf.index.unwrap_or(0);
1274
1275 dns_registry_map
1277 .entry(if_index)
1278 .or_insert_with(DnsRegistry::new);
1279
1280 my_intfs
1281 .entry(if_index)
1282 .and_modify(|v: &mut MyIntf| {
1283 v.addrs.insert(intf.addr.clone());
1284 })
1285 .or_insert(MyIntf {
1286 name: intf.name.clone(),
1287 index: if_index,
1288 addrs: HashSet::from([intf.addr]),
1289 });
1290 }
1291
1292 let monitors = Vec::new();
1293 let service_name_len_max = SERVICE_NAME_LEN_MAX_DEFAULT;
1294 let ip_check_interval = IP_CHECK_INTERVAL_IN_SECS_DEFAULT as u64 * 1000;
1295
1296 let timers = BinaryHeap::new();
1297
1298 let if_selections = vec![];
1300
1301 let status = DaemonStatus::Running;
1302
1303 Self {
1304 port,
1305 my_intfs,
1306 ipv4_sock,
1307 ipv6_sock,
1308 my_services: HashMap::new(),
1309 cache: DnsCache::new(),
1310 dns_registry_map,
1311 hostname_resolvers: HashMap::new(),
1312 service_queriers: HashMap::new(),
1313 retransmissions: Vec::new(),
1314 delayed_responses: Vec::new(),
1315 counters: HashMap::new(),
1316 poller,
1317 monitors,
1318 service_name_len_max,
1319 ip_check_interval,
1320 if_selections,
1321 signal_sock,
1322 timers,
1323 status,
1324 pending_resolves: HashSet::new(),
1325 resolved: HashSet::new(),
1326 multicast_loop_v4: true,
1327 multicast_loop_v6: true,
1328 accept_unsolicited: false,
1329 include_apple_p2p: false,
1330 cmd_sender,
1331 signal_addr,
1332
1333 #[cfg(test)]
1334 test_down_interfaces: HashSet::new(),
1335 }
1336 }
1337
1338 fn send_cmd_to_self(&self, cmd: Command) -> Result<()> {
1340 let cmd_name = cmd.to_string();
1341
1342 self.cmd_sender.try_send(cmd).map_err(|e| match e {
1343 TrySendError::Full(_) => Error::Again,
1344 TrySendError::Disconnected(_) => Error::DaemonShutdown,
1345 })?;
1346
1347 let addr = SocketAddrV4::new(LOOPBACK_V4, 0);
1348 let socket = UdpSocket::bind(addr)
1349 .map_err(|e| e_fmt!("Failed to create socket to send signal: {}", e))?;
1350 socket
1351 .send_to(cmd_name.as_bytes(), self.signal_addr)
1352 .map_err(|e| {
1353 e_fmt!(
1354 "signal socket send_to {} ({}) failed: {}",
1355 self.signal_addr,
1356 cmd_name,
1357 e
1358 )
1359 })?;
1360
1361 Ok(())
1362 }
1363
1364 fn cleanup(&mut self) {
1373 debug!("Starting cleanup for shutdown");
1374
1375 let service_names: Vec<String> = self.my_services.keys().cloned().collect();
1377 for fullname in service_names {
1378 if let Some(info) = self.my_services.get(&fullname) {
1379 debug!("Unregistering service during shutdown: {}", &fullname);
1380
1381 for intf in self.my_intfs.values() {
1382 if let Some(sock) = self.ipv4_sock.as_ref() {
1383 self.unregister_service(info, intf, &sock.pktinfo);
1384 }
1385
1386 if let Some(sock) = self.ipv6_sock.as_ref() {
1387 self.unregister_service(info, intf, &sock.pktinfo);
1388 }
1389 }
1390 }
1391 }
1392 self.my_services.clear();
1393
1394 let browse_types: Vec<String> = self.service_queriers.keys().cloned().collect();
1396 for ty_domain in browse_types {
1397 debug!("Stopping browse during shutdown: {}", &ty_domain);
1398 if let Some(sender) = self.service_queriers.remove(&ty_domain) {
1399 if let Err(e) = sender.send(ServiceEvent::SearchStopped(ty_domain.clone())) {
1401 debug!("Failed to send SearchStopped during shutdown: {}", e);
1402 }
1403 }
1404 }
1405
1406 let hostnames: Vec<String> = self.hostname_resolvers.keys().cloned().collect();
1408 for hostname in hostnames {
1409 debug!(
1410 "Stopping hostname resolution during shutdown: {}",
1411 &hostname
1412 );
1413 if let Some((sender, _timeout)) = self.hostname_resolvers.remove(&hostname) {
1414 if let Err(e) =
1416 sender.send(HostnameResolutionEvent::SearchStopped(hostname.clone()))
1417 {
1418 debug!(
1419 "Failed to send HostnameResolutionEvent::SearchStopped during shutdown: {}",
1420 e
1421 );
1422 }
1423 }
1424 }
1425
1426 self.retransmissions.clear();
1428
1429 self.delayed_responses.clear();
1431
1432 debug!("Cleanup completed");
1433 }
1434
1435 fn run(&mut self, receiver: Receiver<Command>) -> Option<Command> {
1444 if let Err(e) = self.poller.registry().register(
1446 &mut self.signal_sock,
1447 mio::Token(SIGNAL_SOCK_EVENT_KEY),
1448 mio::Interest::READABLE,
1449 ) {
1450 debug!("failed to add signal socket to the poller: {}", e);
1451 return None;
1452 }
1453
1454 if let Some(sock) = self.ipv4_sock.as_mut() {
1455 if let Err(e) = self.poller.registry().register(
1456 sock,
1457 mio::Token(IPV4_SOCK_EVENT_KEY),
1458 mio::Interest::READABLE,
1459 ) {
1460 debug!("failed to register ipv4 socket: {}", e);
1461 return None;
1462 }
1463 }
1464
1465 if let Some(sock) = self.ipv6_sock.as_mut() {
1466 if let Err(e) = self.poller.registry().register(
1467 sock,
1468 mio::Token(IPV6_SOCK_EVENT_KEY),
1469 mio::Interest::READABLE,
1470 ) {
1471 debug!("failed to register ipv6 socket: {}", e);
1472 return None;
1473 }
1474 }
1475
1476 let mut next_ip_check = if self.ip_check_interval > 0 {
1478 current_time_millis() + self.ip_check_interval
1479 } else {
1480 0
1481 };
1482
1483 if next_ip_check > 0 {
1484 self.add_timer(next_ip_check);
1485 }
1486
1487 let mut events = mio::Events::with_capacity(1024);
1490 loop {
1491 let now = current_time_millis();
1492
1493 let earliest_timer = self.peek_earliest_timer();
1494 let timeout = earliest_timer.map(|timer| {
1495 let millis = if timer > now { timer - now } else { 1 };
1497 Duration::from_millis(millis)
1498 });
1499
1500 events.clear();
1502 match self.poller.poll(&mut events, timeout) {
1503 Ok(_) => self.handle_poller_events(&events),
1504 Err(e) => debug!("failed to select from sockets: {}", e),
1505 }
1506
1507 let now = current_time_millis();
1508
1509 self.pop_timers_till(now);
1511
1512 for hostname in self
1514 .hostname_resolvers
1515 .clone()
1516 .into_iter()
1517 .filter(|(_, (_, timeout))| timeout.map(|t| now >= t).unwrap_or(false))
1518 .map(|(hostname, _)| hostname)
1519 {
1520 trace!("hostname resolver timeout for {}", &hostname);
1521 call_hostname_resolution_listener(
1522 &self.hostname_resolvers,
1523 &hostname,
1524 HostnameResolutionEvent::SearchTimeout(hostname.to_owned()),
1525 );
1526 call_hostname_resolution_listener(
1527 &self.hostname_resolvers,
1528 &hostname,
1529 HostnameResolutionEvent::SearchStopped(hostname.to_owned()),
1530 );
1531 self.hostname_resolvers.remove(&hostname);
1532 }
1533
1534 while let Ok(command) = receiver.try_recv() {
1536 if matches!(command, Command::Exit(_)) {
1537 debug!("Exit command received, performing cleanup");
1538 self.cleanup();
1539 self.status = DaemonStatus::Shutdown;
1540 return Some(command);
1541 }
1542 self.exec_command(command, false);
1543 }
1544
1545 let mut i = 0;
1547 while i < self.retransmissions.len() {
1548 if now >= self.retransmissions[i].next_time {
1549 let rerun = self.retransmissions.remove(i);
1550 self.exec_command(rerun.command, true);
1551 } else {
1552 i += 1;
1553 }
1554 }
1555
1556 let mut i = 0;
1558 while i < self.delayed_responses.len() {
1559 if now >= self.delayed_responses[i].next_time {
1560 let resp = self.delayed_responses.remove(i);
1561 self.send_delayed_response(resp);
1562 } else {
1563 i += 1;
1564 }
1565 }
1566
1567 self.refresh_active_services();
1569
1570 let mut query_count = 0;
1572 for (hostname, _sender) in self.hostname_resolvers.iter() {
1573 for (hostname, ip_addr) in
1574 self.cache.refresh_due_hostname_resolutions(hostname).iter()
1575 {
1576 self.send_query(hostname, ip_address_rr_type(&ip_addr.to_ip_addr()));
1577 query_count += 1;
1578 }
1579 }
1580
1581 self.increase_counter(Counter::CacheRefreshAddr, query_count);
1582
1583 let now = current_time_millis();
1585
1586 let expired_services = self.cache.evict_expired_services(now);
1588 if !expired_services.is_empty() {
1589 debug!(
1590 "run: send {} service removal to listeners",
1591 expired_services.len()
1592 );
1593 self.notify_service_removal(expired_services);
1594 }
1595
1596 let expired_addrs = self.cache.evict_expired_addr(now);
1598 for (hostname, addrs) in expired_addrs {
1599 call_hostname_resolution_listener(
1600 &self.hostname_resolvers,
1601 &hostname,
1602 HostnameResolutionEvent::AddressesRemoved(hostname.clone(), addrs),
1603 );
1604 let instances = self.cache.get_instances_on_host(&hostname);
1605 let instance_set: HashSet<String> = instances.into_iter().collect();
1606 self.resolve_updated_instances(&instance_set);
1607 }
1608
1609 self.probing_handler();
1611
1612 if now >= next_ip_check && next_ip_check > 0 {
1614 next_ip_check = now + self.ip_check_interval;
1615 self.add_timer(next_ip_check);
1616
1617 self.check_ip_changes();
1618 }
1619 }
1620 }
1621
1622 fn process_set_option(&mut self, daemon_opt: DaemonOption) {
1623 match daemon_opt {
1624 DaemonOption::ServiceNameLenMax(length) => self.service_name_len_max = length,
1625 DaemonOption::IpCheckInterval(interval) => self.ip_check_interval = interval,
1626 DaemonOption::EnableInterface(if_kind) => self.enable_interface(if_kind),
1627 DaemonOption::DisableInterface(if_kind) => self.disable_interface(if_kind),
1628 DaemonOption::MulticastLoopV4(on) => self.set_multicast_loop_v4(on),
1629 DaemonOption::MulticastLoopV6(on) => self.set_multicast_loop_v6(on),
1630 DaemonOption::AcceptUnsolicited(accept) => self.set_accept_unsolicited(accept),
1631 DaemonOption::IncludeAppleP2P(enable) => self.set_apple_p2p(enable),
1632 #[cfg(test)]
1633 DaemonOption::TestDownInterface(ifname) => {
1634 self.test_down_interfaces.insert(ifname);
1635 }
1636 #[cfg(test)]
1637 DaemonOption::TestUpInterface(ifname) => {
1638 self.test_down_interfaces.remove(&ifname);
1639 }
1640 }
1641 }
1642
1643 fn enable_interface(&mut self, kinds: Vec<IfKind>) {
1644 debug!("enable_interface: {:?}", kinds);
1645 let interfaces = my_ip_interfaces_inner(true, self.include_apple_p2p);
1646
1647 for if_kind in kinds {
1648 self.if_selections.push(IfSelection {
1649 if_kind: resolve_addr_to_index(if_kind, &interfaces),
1650 selected: true,
1651 });
1652 }
1653
1654 self.apply_intf_selections(interfaces);
1655 }
1656
1657 fn disable_interface(&mut self, kinds: Vec<IfKind>) {
1658 debug!("disable_interface: {:?}", kinds);
1659 let interfaces = my_ip_interfaces_inner(true, self.include_apple_p2p);
1660
1661 for if_kind in kinds {
1662 self.if_selections.push(IfSelection {
1663 if_kind: resolve_addr_to_index(if_kind, &interfaces),
1664 selected: false,
1665 });
1666 }
1667
1668 self.apply_intf_selections(interfaces);
1669 }
1670
1671 fn set_multicast_loop_v4(&mut self, on: bool) {
1672 let Some(sock) = self.ipv4_sock.as_mut() else {
1673 return;
1674 };
1675 self.multicast_loop_v4 = on;
1676 sock.pktinfo
1677 .set_multicast_loop_v4(on)
1678 .map_err(|e| e_fmt!("failed to set multicast loop v4: {}", e))
1679 .unwrap();
1680 }
1681
1682 fn set_multicast_loop_v6(&mut self, on: bool) {
1683 let Some(sock) = self.ipv6_sock.as_mut() else {
1684 return;
1685 };
1686 self.multicast_loop_v6 = on;
1687 sock.pktinfo
1688 .set_multicast_loop_v6(on)
1689 .map_err(|e| e_fmt!("failed to set multicast loop v6: {}", e))
1690 .unwrap();
1691 }
1692
1693 fn set_accept_unsolicited(&mut self, accept: bool) {
1694 self.accept_unsolicited = accept;
1695 }
1696
1697 fn set_apple_p2p(&mut self, include: bool) {
1698 if self.include_apple_p2p != include {
1699 self.include_apple_p2p = include;
1700 self.apply_intf_selections(my_ip_interfaces_inner(true, self.include_apple_p2p));
1701 }
1702 }
1703
1704 fn notify_monitors(&mut self, event: DaemonEvent) {
1705 self.monitors.retain(|sender| {
1707 if let Err(e) = sender.try_send(event.clone()) {
1708 debug!("notify_monitors: try_send: {}", &e);
1709 if matches!(e, TrySendError::Disconnected(_)) {
1710 return false; }
1712 }
1713 true
1714 });
1715 }
1716
1717 fn del_addr_in_my_services(&mut self, addr: &IpAddr) {
1719 for (_, service_info) in self.my_services.iter_mut() {
1720 if service_info.is_addr_auto() {
1721 service_info.remove_ipaddr(addr);
1722 }
1723 }
1724 }
1725
1726 fn add_timer(&mut self, next_time: u64) {
1727 self.timers.push(Reverse(next_time));
1728 }
1729
1730 fn peek_earliest_timer(&self) -> Option<u64> {
1731 self.timers.peek().map(|Reverse(v)| *v)
1732 }
1733
1734 fn _pop_earliest_timer(&mut self) -> Option<u64> {
1735 self.timers.pop().map(|Reverse(v)| v)
1736 }
1737
1738 fn pop_timers_till(&mut self, now: u64) {
1740 while let Some(Reverse(v)) = self.timers.peek() {
1741 if *v > now {
1742 break;
1743 }
1744 self.timers.pop();
1745 }
1746 }
1747
1748 fn selected_intfs(&self, interfaces: Vec<Interface>) -> HashSet<Interface> {
1750 let intf_count = interfaces.len();
1751 let mut intf_selections = vec![true; intf_count];
1752
1753 for selection in self.if_selections.iter() {
1755 for i in 0..intf_count {
1757 if selection.if_kind.matches(&interfaces[i]) {
1758 intf_selections[i] = selection.selected;
1759 }
1760 }
1761 }
1762
1763 let mut selected_addrs = HashSet::new();
1764 for i in 0..intf_count {
1765 if intf_selections[i] {
1766 selected_addrs.insert(interfaces[i].clone());
1767 }
1768 }
1769
1770 selected_addrs
1771 }
1772
1773 fn apply_intf_selections(&mut self, interfaces: Vec<Interface>) {
1778 let intf_count = interfaces.len();
1780 let mut intf_selections = vec![true; intf_count];
1781
1782 for selection in self.if_selections.iter() {
1784 for i in 0..intf_count {
1786 if selection.if_kind.matches(&interfaces[i]) {
1787 intf_selections[i] = selection.selected;
1788 }
1789 }
1790 }
1791
1792 for (idx, intf) in interfaces.into_iter().enumerate() {
1794 if intf_selections[idx] {
1795 self.add_interface(intf);
1797 } else {
1798 self.del_interface_addr(&intf);
1800 }
1801 }
1802 }
1803
1804 fn del_ip(&mut self, ip: IpAddr) {
1805 self.del_addr_in_my_services(&ip);
1806 self.notify_monitors(DaemonEvent::IpDel(ip));
1807 }
1808
1809 fn check_ip_changes(&mut self) {
1811 let my_ifaddrs = my_ip_interfaces_inner(true, self.include_apple_p2p);
1813
1814 #[cfg(test)]
1815 let my_ifaddrs: Vec<_> = my_ifaddrs
1816 .into_iter()
1817 .filter(|intf| !self.test_down_interfaces.contains(&intf.name))
1818 .collect();
1819
1820 let ifaddrs_map: HashMap<u32, Vec<&IfAddr>> =
1821 my_ifaddrs.iter().fold(HashMap::new(), |mut acc, intf| {
1822 let if_index = intf.index.unwrap_or(0);
1823 acc.entry(if_index).or_default().push(&intf.addr);
1824 acc
1825 });
1826
1827 let mut deleted_intfs = Vec::new();
1828 let mut deleted_ips = Vec::new();
1829
1830 for (if_index, my_intf) in self.my_intfs.iter_mut() {
1831 let mut last_ipv4 = None;
1832 let mut last_ipv6 = None;
1833
1834 if let Some(current_addrs) = ifaddrs_map.get(if_index) {
1835 my_intf.addrs.retain(|addr| {
1836 if current_addrs.contains(&addr) {
1837 true
1838 } else {
1839 match addr.ip() {
1840 IpAddr::V4(ipv4) => last_ipv4 = Some(ipv4),
1841 IpAddr::V6(ipv6) => last_ipv6 = Some(ipv6),
1842 }
1843 deleted_ips.push(addr.ip());
1844 false
1845 }
1846 });
1847 if my_intf.addrs.is_empty() {
1848 deleted_intfs.push((*if_index, last_ipv4, last_ipv6))
1849 }
1850 } else {
1851 debug!(
1853 "check_ip_changes: interface {} ({}) no longer exists, removing",
1854 my_intf.name, if_index
1855 );
1856 for addr in my_intf.addrs.iter() {
1857 match addr.ip() {
1858 IpAddr::V4(ipv4) => last_ipv4 = Some(ipv4),
1859 IpAddr::V6(ipv6) => last_ipv6 = Some(ipv6),
1860 }
1861 deleted_ips.push(addr.ip())
1862 }
1863 deleted_intfs.push((*if_index, last_ipv4, last_ipv6));
1864 }
1865 }
1866
1867 if !deleted_ips.is_empty() || !deleted_intfs.is_empty() {
1868 debug!(
1869 "check_ip_changes: {} deleted ips {} deleted intfs",
1870 deleted_ips.len(),
1871 deleted_intfs.len()
1872 );
1873 }
1874
1875 for ip in deleted_ips {
1876 self.del_ip(ip);
1877 }
1878
1879 for (if_index, last_ipv4, last_ipv6) in deleted_intfs {
1880 let Some(my_intf) = self.my_intfs.remove(&if_index) else {
1881 continue;
1882 };
1883
1884 if let Some(ipv4) = last_ipv4 {
1885 debug!("leave multicast for {ipv4}");
1886 if let Some(sock) = self.ipv4_sock.as_mut() {
1887 if let Err(e) = sock.pktinfo.leave_multicast_v4(&GROUP_ADDR_V4, &ipv4) {
1888 debug!("leave multicast group for addr {ipv4}: {e}");
1889 }
1890 }
1891 }
1892
1893 if let Some(ipv6) = last_ipv6 {
1894 debug!("leave multicast for {ipv6}");
1895 if let Some(sock) = self.ipv6_sock.as_mut() {
1896 if let Err(e) = sock
1897 .pktinfo
1898 .leave_multicast_v6(&GROUP_ADDR_V6, my_intf.index)
1899 {
1900 debug!("leave multicast group for IPv6: {ipv6}: {e}");
1901 }
1902 }
1903 }
1904
1905 let intf_id = InterfaceId {
1907 name: my_intf.name.to_string(),
1908 index: my_intf.index,
1909 };
1910 let result = self.cache.remove_records_on_intf(intf_id);
1911 self.notify_service_removal(result.removed_instances);
1912 self.resolve_updated_instances(&result.modified_instances);
1913 }
1914
1915 self.apply_intf_selections(my_ifaddrs);
1917 }
1918
1919 fn del_interface_addr(&mut self, intf: &Interface) {
1922 let if_index = intf.index.unwrap_or(0);
1923 debug!(
1924 "del_interface_addr: {} ({if_index}) addr {}",
1925 intf.name,
1926 intf.ip()
1927 );
1928
1929 let Some(my_intf) = self.my_intfs.get_mut(&if_index) else {
1930 debug!("del_interface_addr: interface {} not found", intf.name);
1931 return;
1932 };
1933
1934 let mut ip_removed = false;
1935
1936 if my_intf.addrs.remove(&intf.addr) {
1937 ip_removed = true;
1938
1939 match intf.addr.ip() {
1940 IpAddr::V4(ipv4) => {
1941 if my_intf.next_ifaddr_v4().is_none() {
1942 if let Some(sock) = self.ipv4_sock.as_mut() {
1943 if let Err(e) = sock.pktinfo.leave_multicast_v4(&GROUP_ADDR_V4, &ipv4) {
1944 debug!("leave multicast group for addr {ipv4}: {e}");
1945 } else {
1946 debug!("leave multicast for {ipv4}");
1947 }
1948 }
1949 }
1950 }
1951
1952 IpAddr::V6(ipv6) => {
1953 if my_intf.next_ifaddr_v6().is_none() {
1954 if let Some(sock) = self.ipv6_sock.as_mut() {
1955 if let Err(e) =
1956 sock.pktinfo.leave_multicast_v6(&GROUP_ADDR_V6, if_index)
1957 {
1958 debug!("leave multicast group for addr {ipv6}: {e}");
1959 }
1960 }
1961 }
1962 }
1963 }
1964
1965 if my_intf.addrs.is_empty() {
1966 debug!("del_interface_addr: removing interface {}", intf.name);
1968 self.my_intfs.remove(&if_index);
1969 self.dns_registry_map.remove(&if_index);
1970 self.cache
1971 .remove_addrs_on_disabled_intf(if_index, IpType::BOTH);
1972 } else {
1973 let is_v4 = intf.addr.ip().is_ipv4();
1977 let version_gone = if is_v4 {
1978 my_intf.next_ifaddr_v4().is_none()
1979 } else {
1980 my_intf.next_ifaddr_v6().is_none()
1981 };
1982 if version_gone {
1983 let ip_type = if is_v4 { IpType::V4 } else { IpType::V6 };
1984 self.cache.remove_addrs_on_disabled_intf(if_index, ip_type);
1985 }
1986 }
1987 }
1988
1989 if ip_removed {
1990 self.notify_monitors(DaemonEvent::IpDel(intf.ip()));
1992 self.del_addr_in_my_services(&intf.ip());
1994 }
1995 }
1996
1997 fn add_interface(&mut self, intf: Interface) {
1998 let sock_opt = if intf.ip().is_ipv4() {
1999 &self.ipv4_sock
2000 } else {
2001 &self.ipv6_sock
2002 };
2003
2004 let Some(sock) = sock_opt else {
2005 debug!(
2006 "add_interface: no socket available for interface {} with addr {}. Skipped.",
2007 intf.name,
2008 intf.ip()
2009 );
2010 return;
2011 };
2012
2013 let if_index = intf.index.unwrap_or(0);
2014 let mut new_addr = false;
2015
2016 match self.my_intfs.entry(if_index) {
2017 Entry::Occupied(mut entry) => {
2018 let my_intf = entry.get_mut();
2020 if !my_intf.addrs.contains(&intf.addr) {
2021 if let Err(e) = join_multicast_group(&sock.pktinfo, &intf) {
2022 debug!("add_interface: socket_config {}: {e}", &intf.name);
2023 }
2024 my_intf.addrs.insert(intf.addr.clone());
2025 new_addr = true;
2026 }
2027 }
2028 Entry::Vacant(entry) => {
2029 if let Err(e) = join_multicast_group(&sock.pktinfo, &intf) {
2030 debug!("add_interface: socket_config {}: {e}. Skipped.", &intf.name);
2031 return;
2032 }
2033
2034 new_addr = true;
2035 let new_intf = MyIntf {
2036 name: intf.name.clone(),
2037 index: if_index,
2038 addrs: HashSet::from([intf.addr.clone()]),
2039 };
2040 entry.insert(new_intf);
2041 }
2042 }
2043
2044 if !new_addr {
2045 trace!("add_interface: interface {} already exists", &intf.name);
2046 return;
2047 }
2048
2049 debug!("add new interface {}: {}", intf.name, intf.ip());
2050
2051 let Some(my_intf) = self.my_intfs.get(&if_index) else {
2052 debug!("add_interface: cannot find if_index {if_index}");
2053 return;
2054 };
2055
2056 let dns_registry = match self.dns_registry_map.get_mut(&if_index) {
2057 Some(registry) => registry,
2058 None => self
2059 .dns_registry_map
2060 .entry(if_index)
2061 .or_insert_with(DnsRegistry::new),
2062 };
2063
2064 for (_, service_info) in self.my_services.iter_mut() {
2065 if service_info.is_addr_auto() {
2066 service_info.insert_ipaddr(&intf);
2067
2068 if let Ok(true) = announce_service_on_intf(
2069 dns_registry,
2070 service_info,
2071 my_intf,
2072 &sock.pktinfo,
2073 self.port,
2074 ) {
2075 debug!(
2076 "Announce service {} on {}",
2077 service_info.get_fullname(),
2078 intf.ip()
2079 );
2080 service_info.set_status(if_index, ServiceStatus::Announced);
2081 } else {
2082 for timer in dns_registry.new_timers.drain(..) {
2083 self.timers.push(Reverse(timer));
2084 }
2085 service_info.set_status(if_index, ServiceStatus::Probing);
2086 }
2087 }
2088 }
2089
2090 if let Some(my_intf) = self.my_intfs.get(&if_index) {
2095 for ty in self.service_queriers.keys() {
2096 self.send_query_on_intf(ty, RRType::PTR, my_intf);
2097 }
2098 }
2099
2100 self.notify_monitors(DaemonEvent::IpAdd(intf.ip()));
2102 }
2103
2104 fn register_service(&mut self, mut info: ServiceInfo) {
2113 if let Err(e) = check_service_name_length(info.get_type(), self.service_name_len_max) {
2115 error!("check_service_name_length: {}", &e);
2116 self.notify_monitors(DaemonEvent::Error(e));
2117 return;
2118 }
2119
2120 if info.is_addr_auto() {
2121 let selected_intfs =
2122 self.selected_intfs(my_ip_interfaces_inner(true, self.include_apple_p2p));
2123 for intf in selected_intfs {
2124 info.insert_ipaddr(&intf);
2125 }
2126 }
2127
2128 debug!("register service {:?}", &info);
2129
2130 let outgoing_addrs = self.send_unsolicited_response(&mut info);
2131 if !outgoing_addrs.is_empty() {
2132 self.notify_monitors(DaemonEvent::Announce(
2133 info.get_fullname().to_string(),
2134 format!("{:?}", &outgoing_addrs),
2135 ));
2136 }
2137
2138 let service_fullname = info.get_fullname().to_lowercase();
2141 self.my_services.insert(service_fullname, info);
2142 }
2143
2144 fn send_unsolicited_response(&mut self, info: &mut ServiceInfo) -> Vec<IpAddr> {
2147 let mut outgoing_addrs = Vec::new();
2148 let mut outgoing_intfs = HashSet::new();
2149
2150 let mut invalid_intf_addrs = HashSet::new();
2151
2152 for (if_index, intf) in self.my_intfs.iter() {
2153 let dns_registry = match self.dns_registry_map.get_mut(if_index) {
2154 Some(registry) => registry,
2155 None => self
2156 .dns_registry_map
2157 .entry(*if_index)
2158 .or_insert_with(DnsRegistry::new),
2159 };
2160
2161 let mut announced = false;
2162
2163 if let Some(sock) = self.ipv4_sock.as_mut() {
2165 match announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port) {
2166 Ok(true) => {
2167 for addr in intf.addrs.iter().filter(|a| a.ip().is_ipv4()) {
2168 outgoing_addrs.push(addr.ip());
2169 }
2170 outgoing_intfs.insert(intf.index);
2171
2172 debug!(
2173 "Announce service IPv4 {} on {}",
2174 info.get_fullname(),
2175 intf.name
2176 );
2177 announced = true;
2178 }
2179 Ok(false) => {}
2180 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2181 invalid_intf_addrs.insert(intf_addr);
2182 }
2183 }
2184 }
2185
2186 if let Some(sock) = self.ipv6_sock.as_mut() {
2187 match announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port) {
2188 Ok(true) => {
2189 for addr in intf.addrs.iter().filter(|a| a.ip().is_ipv6()) {
2190 outgoing_addrs.push(addr.ip());
2191 }
2192 outgoing_intfs.insert(intf.index);
2193
2194 debug!(
2195 "Announce service IPv6 {} on {}",
2196 info.get_fullname(),
2197 intf.name
2198 );
2199 announced = true;
2200 }
2201 Ok(false) => {}
2202 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2203 invalid_intf_addrs.insert(intf_addr);
2204 }
2205 }
2206 }
2207
2208 if announced {
2209 info.set_status(intf.index, ServiceStatus::Announced);
2210 } else {
2211 for timer in dns_registry.new_timers.drain(..) {
2212 self.timers.push(Reverse(timer));
2213 }
2214 info.set_status(*if_index, ServiceStatus::Probing);
2215 }
2216 }
2217
2218 if !invalid_intf_addrs.is_empty() {
2219 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2220 }
2221
2222 let next_time = current_time_millis()
2226 + ANNOUNCE_SECOND_DELAY_MILLIS
2227 + fastrand::u64(0..ANNOUNCE_SECOND_JITTER_MILLIS);
2228 for if_index in outgoing_intfs {
2229 self.add_retransmission(
2230 next_time,
2231 Command::RegisterResend(info.get_fullname().to_string(), if_index),
2232 );
2233 }
2234
2235 outgoing_addrs
2236 }
2237
2238 fn probing_handler(&mut self) {
2240 let now = current_time_millis();
2241 let mut invalid_intf_addrs = HashSet::new();
2242
2243 for (if_index, intf) in self.my_intfs.iter() {
2244 let Some(dns_registry) = self.dns_registry_map.get_mut(if_index) else {
2245 continue;
2246 };
2247
2248 let (out, expired_probes) = check_probing(dns_registry, &mut self.timers, now);
2249
2250 if !out.questions().is_empty() {
2252 trace!("sending out probing of questions: {:?}", out.questions());
2253 if let Some(sock) = self.ipv4_sock.as_mut() {
2254 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2255 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2256 {
2257 invalid_intf_addrs.insert(intf_addr);
2258 }
2259 }
2260 if let Some(sock) = self.ipv6_sock.as_mut() {
2261 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2262 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2263 {
2264 invalid_intf_addrs.insert(intf_addr);
2265 }
2266 }
2267 }
2268
2269 let waiting_services =
2271 handle_expired_probes(expired_probes, &intf.name, dns_registry, &mut self.monitors);
2272
2273 for service_name in waiting_services {
2274 if let Some(info) = self.my_services.get_mut(&service_name.to_lowercase()) {
2276 if info.get_status(*if_index) == ServiceStatus::Announced {
2277 debug!("service {} already announced", info.get_fullname());
2278 continue;
2279 }
2280
2281 let announced_v4 = if let Some(sock) = self.ipv4_sock.as_mut() {
2282 match announce_service_on_intf(
2283 dns_registry,
2284 info,
2285 intf,
2286 &sock.pktinfo,
2287 self.port,
2288 ) {
2289 Ok(announced) => announced,
2290 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2291 invalid_intf_addrs.insert(intf_addr);
2292 false
2293 }
2294 }
2295 } else {
2296 false
2297 };
2298 let announced_v6 = if let Some(sock) = self.ipv6_sock.as_mut() {
2299 match announce_service_on_intf(
2300 dns_registry,
2301 info,
2302 intf,
2303 &sock.pktinfo,
2304 self.port,
2305 ) {
2306 Ok(announced) => announced,
2307 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2308 invalid_intf_addrs.insert(intf_addr);
2309 false
2310 }
2311 }
2312 } else {
2313 false
2314 };
2315
2316 if announced_v4 || announced_v6 {
2317 let next_time = now
2318 + ANNOUNCE_SECOND_DELAY_MILLIS
2319 + fastrand::u64(0..ANNOUNCE_SECOND_JITTER_MILLIS);
2320 let command =
2321 Command::RegisterResend(info.get_fullname().to_string(), *if_index);
2322 self.retransmissions.push(ReRun { next_time, command });
2323 self.timers.push(Reverse(next_time));
2324
2325 let fullname = dns_registry.resolve_name(&service_name).to_string();
2326
2327 let hostname = dns_registry.resolve_name(info.get_hostname());
2328
2329 debug!("wake up: announce service {} on {}", fullname, intf.name);
2330 notify_monitors(
2331 &mut self.monitors,
2332 DaemonEvent::Announce(fullname, format!("{}:{}", hostname, &intf.name)),
2333 );
2334
2335 info.set_status(*if_index, ServiceStatus::Announced);
2336 }
2337 }
2338 }
2339 }
2340
2341 if !invalid_intf_addrs.is_empty() {
2342 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2343 }
2344 }
2345
2346 fn unregister_service(
2347 &self,
2348 info: &ServiceInfo,
2349 intf: &MyIntf,
2350 sock: &PktInfoUdpSocket,
2351 ) -> Vec<u8> {
2352 let is_ipv4 = sock.domain() == Domain::IPV4;
2353
2354 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
2355 out.add_answer_at_time(
2356 DnsPointer::new(
2357 info.get_type(),
2358 RRType::PTR,
2359 CLASS_IN,
2360 0,
2361 info.get_fullname().to_string(),
2362 ),
2363 0,
2364 );
2365
2366 if let Some(sub) = info.get_subtype() {
2367 trace!("Adding subdomain {}", sub);
2368 out.add_answer_at_time(
2369 DnsPointer::new(
2370 sub,
2371 RRType::PTR,
2372 CLASS_IN,
2373 0,
2374 info.get_fullname().to_string(),
2375 ),
2376 0,
2377 );
2378 }
2379
2380 out.add_answer_at_time(
2381 DnsSrv::new(
2382 info.get_fullname(),
2383 CLASS_IN | CLASS_CACHE_FLUSH,
2384 0,
2385 info.get_priority(),
2386 info.get_weight(),
2387 info.get_port(),
2388 info.get_hostname().to_string(),
2389 ),
2390 0,
2391 );
2392 out.add_answer_at_time(
2393 DnsTxt::new(
2394 info.get_fullname(),
2395 CLASS_IN | CLASS_CACHE_FLUSH,
2396 0,
2397 info.generate_txt(),
2398 ),
2399 0,
2400 );
2401
2402 let if_addrs = if is_ipv4 {
2403 info.get_addrs_on_my_intf_v4(intf)
2404 } else {
2405 info.get_addrs_on_my_intf_v6(intf)
2406 };
2407
2408 if if_addrs.is_empty() {
2409 return vec![];
2410 }
2411
2412 for address in if_addrs {
2413 out.add_answer_at_time(
2414 DnsAddress::new(
2415 info.get_hostname(),
2416 ip_address_rr_type(&address),
2417 CLASS_IN | CLASS_CACHE_FLUSH,
2418 0,
2419 address,
2420 intf.into(),
2421 ),
2422 0,
2423 );
2424 }
2425
2426 let sent_vec = match send_dns_outgoing(&out, intf, sock, self.port, None, None) {
2428 Ok(sent_vec) => sent_vec,
2429 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2430 let invalid_intf_addrs = HashSet::from([intf_addr]);
2431 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2432 vec![]
2433 }
2434 };
2435 sent_vec.into_iter().next().unwrap_or_default()
2436 }
2437
2438 fn add_hostname_resolver(
2442 &mut self,
2443 hostname: String,
2444 listener: Sender<HostnameResolutionEvent>,
2445 timeout: Option<u64>,
2446 ) {
2447 let real_timeout = timeout.map(|t| current_time_millis() + t);
2448 self.hostname_resolvers
2449 .insert(hostname.to_lowercase(), (listener, real_timeout));
2450 if let Some(t) = real_timeout {
2451 self.add_timer(t);
2452 }
2453 }
2454
2455 fn send_query(&self, name: &str, qtype: RRType) {
2457 self.send_query_vec(&[(name, qtype)]);
2458 }
2459
2460 fn send_query_on_intf(&self, name: &str, qtype: RRType, intf: &MyIntf) {
2465 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2466 out.add_question(name, qtype);
2467
2468 let mut invalid_intf_addrs = HashSet::new();
2469 if let Some(sock) = self.ipv4_sock.as_ref() {
2470 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2471 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2472 {
2473 invalid_intf_addrs.insert(intf_addr);
2474 }
2475 }
2476 if let Some(sock) = self.ipv6_sock.as_ref() {
2477 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2478 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2479 {
2480 invalid_intf_addrs.insert(intf_addr);
2481 }
2482 }
2483 if !invalid_intf_addrs.is_empty() {
2484 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2485 }
2486 }
2487
2488 fn send_query_vec(&self, questions: &[(&str, RRType)]) {
2490 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2491 let now = current_time_millis();
2492
2493 for (name, qtype) in questions {
2494 out.add_question(name, *qtype);
2495
2496 for record in self.cache.get_known_answers(name, *qtype, now) {
2497 trace!("add known answer: {:?}", record.record);
2505 let mut new_record = record.record.clone();
2506 new_record.get_record_mut().update_ttl(now);
2507 out.add_answer_box(new_record);
2508 }
2509 }
2510
2511 let mut invalid_intf_addrs = HashSet::new();
2512 for (_, intf) in self.my_intfs.iter() {
2513 if let Some(sock) = self.ipv4_sock.as_ref() {
2514 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2515 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2516 {
2517 invalid_intf_addrs.insert(intf_addr);
2518 }
2519 }
2520 if let Some(sock) = self.ipv6_sock.as_ref() {
2521 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2522 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2523 {
2524 invalid_intf_addrs.insert(intf_addr);
2525 }
2526 }
2527 }
2528
2529 if !invalid_intf_addrs.is_empty() {
2530 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2531 }
2532 }
2533
2534 fn handle_read(&mut self, event_key: usize) -> bool {
2539 let sock_opt = match event_key {
2540 IPV4_SOCK_EVENT_KEY => &mut self.ipv4_sock,
2541 IPV6_SOCK_EVENT_KEY => &mut self.ipv6_sock,
2542 _ => {
2543 debug!("handle_read: unknown token {}", event_key);
2544 return false;
2545 }
2546 };
2547 let Some(sock) = sock_opt.as_mut() else {
2548 debug!("handle_read: socket not available for token {}", event_key);
2549 return false;
2550 };
2551 let mut buf = vec![0u8; MAX_MSG_ABSOLUTE];
2552
2553 let (sz, pktinfo) = match sock.pktinfo.recv(&mut buf) {
2560 Ok(sz) => sz,
2561 Err(e) => {
2562 if e.kind() != std::io::ErrorKind::WouldBlock {
2563 debug!("listening socket read failed: {}", e);
2564 }
2565 return false;
2566 }
2567 };
2568
2569 let pkt_if_index = pktinfo.if_index as u32;
2571 let Some(my_intf) = self.my_intfs.get(&pkt_if_index) else {
2572 debug!(
2573 "handle_read: no interface found for pktinfo if_index: {}",
2574 pktinfo.if_index
2575 );
2576 return true; };
2578
2579 let is_ipv4 = event_key == IPV4_SOCK_EVENT_KEY;
2584 if (is_ipv4 && my_intf.next_ifaddr_v4().is_none())
2585 || (!is_ipv4 && my_intf.next_ifaddr_v6().is_none())
2586 {
2587 debug!(
2588 "handle_read: dropping {} packet on intf {} (disabled)",
2589 if is_ipv4 { "IPv4" } else { "IPv6" },
2590 my_intf.name
2591 );
2592 return true;
2593 }
2594
2595 buf.truncate(sz); match DnsIncoming::new(buf, my_intf.into()) {
2598 Ok(msg) => {
2599 if msg.is_query() {
2600 let querier_addr = pktinfo.addr_src;
2601 self.handle_query(msg, pkt_if_index, querier_addr);
2602 } else if msg.is_response() {
2603 self.handle_response(msg, pkt_if_index);
2604 } else {
2605 debug!("Invalid message: not query and not response");
2606 }
2607 }
2608 Err(e) => debug!("Invalid incoming DNS message: {}", e),
2609 }
2610
2611 true
2612 }
2613
2614 fn query_unresolved(&mut self, instance: &str) -> bool {
2616 if !valid_instance_name(instance) {
2617 trace!("instance name {} not valid", instance);
2618 return false;
2619 }
2620
2621 if let Some(records) = self.cache.get_srv(instance) {
2622 for record in records {
2623 if let Some(srv) = record.record.any().downcast_ref::<DnsSrv>() {
2624 if self.cache.get_addr(srv.host()).is_none() {
2625 self.send_query_vec(&[(srv.host(), RRType::A), (srv.host(), RRType::AAAA)]);
2626 return true;
2627 }
2628 }
2629 }
2630 } else {
2631 self.send_query(instance, RRType::ANY);
2632 return true;
2633 }
2634
2635 false
2636 }
2637
2638 fn query_cache_for_service(
2641 &mut self,
2642 ty_domain: &str,
2643 sender: &Sender<ServiceEvent>,
2644 now: u64,
2645 ) {
2646 let mut resolved: HashSet<String> = HashSet::new();
2647 let mut unresolved: HashSet<String> = HashSet::new();
2648
2649 if let Some(records) = self.cache.get_ptr(ty_domain) {
2650 for record in records.iter().filter(|r| !r.record.expires_soon(now)) {
2651 if let Some(ptr) = record.record.any().downcast_ref::<DnsPointer>() {
2652 let mut new_event = None;
2653 match self.resolve_service_from_cache(ty_domain, ptr.alias()) {
2654 Ok(resolved_service) => {
2655 if resolved_service.is_valid() {
2656 debug!("Resolved service from cache: {}", ptr.alias());
2657 new_event =
2658 Some(ServiceEvent::ServiceResolved(Box::new(resolved_service)));
2659 } else {
2660 debug!("Resolved service is not valid: {}", ptr.alias());
2661 }
2662 }
2663 Err(err) => {
2664 debug!("Error while resolving service from cache: {}", err);
2665 continue;
2666 }
2667 }
2668
2669 match sender.send(ServiceEvent::ServiceFound(
2670 ty_domain.to_string(),
2671 ptr.alias().to_string(),
2672 )) {
2673 Ok(()) => debug!("sent service found {}", ptr.alias()),
2674 Err(e) => {
2675 debug!("failed to send service found: {}", e);
2676 continue;
2677 }
2678 }
2679
2680 if let Some(event) = new_event {
2681 resolved.insert(ptr.alias().to_string());
2682 match sender.send(event) {
2683 Ok(()) => debug!("sent service resolved: {}", ptr.alias()),
2684 Err(e) => debug!("failed to send service resolved: {}", e),
2685 }
2686 } else {
2687 unresolved.insert(ptr.alias().to_string());
2688 }
2689 }
2690 }
2691 }
2692
2693 for instance in resolved.drain() {
2694 self.pending_resolves.remove(&instance);
2695 self.resolved.insert(instance);
2696 }
2697
2698 for instance in unresolved.drain() {
2699 self.add_pending_resolve(instance);
2700 }
2701 }
2702
2703 fn query_cache_for_hostname(
2706 &mut self,
2707 hostname: &str,
2708 sender: Sender<HostnameResolutionEvent>,
2709 ) {
2710 let addresses_map = self.cache.get_addresses_for_host(hostname);
2711 for (name, addresses) in addresses_map {
2712 match sender.send(HostnameResolutionEvent::AddressesFound(name, addresses)) {
2713 Ok(()) => trace!("sent hostname addresses found"),
2714 Err(e) => debug!("failed to send hostname addresses found: {}", e),
2715 }
2716 }
2717 }
2718
2719 fn add_pending_resolve(&mut self, instance: String) {
2720 if !self.pending_resolves.contains(&instance) {
2721 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
2722 self.add_retransmission(next_time, Command::Resolve(instance.clone(), 1));
2723 self.pending_resolves.insert(instance);
2724 }
2725 }
2726
2727 fn resolve_service_from_cache(
2729 &self,
2730 ty_domain: &str,
2731 fullname: &str,
2732 ) -> Result<ResolvedService> {
2733 let now = current_time_millis();
2734 let mut resolved_service = ResolvedService {
2735 ty_domain: ty_domain.to_string(),
2736 sub_ty_domain: None,
2737 fullname: fullname.to_string(),
2738 host: String::new(),
2739 port: 0,
2740 addresses: HashSet::new(),
2741 txt_properties: TxtProperties::new(),
2742 };
2743
2744 if let Some(subtype) = self.cache.get_subtype(fullname) {
2746 trace!(
2747 "ty_domain: {} found subtype {} for instance: {}",
2748 ty_domain,
2749 subtype,
2750 fullname
2751 );
2752 if resolved_service.sub_ty_domain.is_none() {
2753 resolved_service.sub_ty_domain = Some(subtype.to_string());
2754 }
2755 }
2756
2757 if let Some(records) = self.cache.get_srv(fullname) {
2759 if let Some(answer) = records.iter().find(|r| !r.record.expires_soon(now)) {
2760 if let Some(dns_srv) = answer.record.any().downcast_ref::<DnsSrv>() {
2761 resolved_service.host = dns_srv.host().to_string();
2762 resolved_service.port = dns_srv.port();
2763 }
2764 }
2765 }
2766
2767 if let Some(records) = self.cache.get_txt(fullname) {
2769 if let Some(record) = records.iter().find(|r| !r.record.expires_soon(now)) {
2770 if let Some(dns_txt) = record.record.any().downcast_ref::<DnsTxt>() {
2771 resolved_service.txt_properties = dns_txt.text().into();
2772 }
2773 }
2774 }
2775
2776 if let Some(records) = self.cache.get_addr(&resolved_service.host) {
2778 for answer in records.iter() {
2779 if let Some(dns_a) = answer.record.any().downcast_ref::<DnsAddress>() {
2780 if dns_a.expires_soon(now) {
2781 trace!(
2782 "Addr expired or expires soon: {}",
2783 dns_a.address().to_ip_addr()
2784 );
2785 } else {
2786 let scoped = dns_a.address();
2787 if let ScopedIp::V4(v4) = &scoped {
2788 let existing = resolved_service
2791 .addresses
2792 .iter()
2793 .find(|a| a.to_ip_addr() == IpAddr::V4(*v4.addr()))
2794 .cloned();
2795 if let Some(mut existing) = existing {
2796 resolved_service.addresses.remove(&existing);
2797 if let ScopedIp::V4(existing_v4) = &mut existing {
2798 for id in v4.interface_ids() {
2799 existing_v4.add_interface_id(id.clone());
2800 }
2801 }
2802 resolved_service.addresses.insert(existing);
2803 } else {
2804 resolved_service.addresses.insert(scoped);
2805 }
2806 } else {
2807 resolved_service.addresses.insert(scoped);
2808 }
2809 }
2810 }
2811 }
2812 }
2813
2814 Ok(resolved_service)
2815 }
2816
2817 fn handle_poller_events(&mut self, events: &mio::Events) {
2818 for ev in events.iter() {
2819 trace!("event received with key {:?}", ev.token());
2820 if ev.token().0 == SIGNAL_SOCK_EVENT_KEY {
2821 self.signal_sock_drain();
2823
2824 if let Err(e) = self.poller.registry().reregister(
2825 &mut self.signal_sock,
2826 ev.token(),
2827 mio::Interest::READABLE,
2828 ) {
2829 debug!("failed to modify poller for signal socket: {}", e);
2830 }
2831 continue; }
2833
2834 while self.handle_read(ev.token().0) {}
2836
2837 if ev.token().0 == IPV4_SOCK_EVENT_KEY {
2839 if let Some(sock) = self.ipv4_sock.as_mut() {
2841 if let Err(e) =
2842 self.poller
2843 .registry()
2844 .reregister(sock, ev.token(), mio::Interest::READABLE)
2845 {
2846 debug!("modify poller for IPv4 socket: {}", e);
2847 }
2848 }
2849 } else if ev.token().0 == IPV6_SOCK_EVENT_KEY {
2850 if let Some(sock) = self.ipv6_sock.as_mut() {
2852 if let Err(e) =
2853 self.poller
2854 .registry()
2855 .reregister(sock, ev.token(), mio::Interest::READABLE)
2856 {
2857 debug!("modify poller for IPv6 socket: {}", e);
2858 }
2859 }
2860 }
2861 }
2862 }
2863
2864 fn handle_response(&mut self, mut msg: DnsIncoming, if_index: u32) {
2867 let now = current_time_millis();
2868
2869 let mut record_predicate = |record: &DnsRecordBox| {
2871 if !record.get_record().is_expired(now) {
2872 return true;
2873 }
2874
2875 debug!("record is expired, removing it from cache.");
2876 if self.cache.remove(record) {
2877 if let Some(dns_ptr) = record.any().downcast_ref::<DnsPointer>() {
2879 call_service_listener(
2880 &self.service_queriers,
2881 dns_ptr.get_name(),
2882 ServiceEvent::ServiceRemoved(
2883 dns_ptr.get_name().to_string(),
2884 dns_ptr.alias().to_string(),
2885 ),
2886 );
2887 }
2888 }
2889 false
2890 };
2891 msg.answers_mut().retain(&mut record_predicate);
2892 msg.authorities_mut().retain(&mut record_predicate);
2893 msg.additionals_mut().retain(&mut record_predicate);
2894
2895 self.conflict_handler(&msg, if_index);
2897
2898 let mut is_for_us = true; for answer in msg.answers() {
2905 if answer.get_type() == RRType::PTR {
2906 if self.service_queriers.contains_key(answer.get_name()) {
2907 is_for_us = true;
2908 break; } else {
2910 is_for_us = false;
2911 }
2912 } else if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
2913 let answer_lowercase = answer.get_name().to_lowercase();
2915 if self.hostname_resolvers.contains_key(&answer_lowercase) {
2916 is_for_us = true;
2917 break; }
2919 }
2920 }
2921
2922 if self.accept_unsolicited {
2924 is_for_us = true;
2925 }
2926
2927 struct InstanceChange {
2929 ty: RRType, name: String, }
2932
2933 let mut changes = Vec::new();
2941 let mut timers = Vec::new();
2942 let Some(my_intf) = self.my_intfs.get(&if_index) else {
2943 return;
2944 };
2945 for record in msg.all_records() {
2946 match self
2947 .cache
2948 .add_or_update(my_intf, record, &mut timers, is_for_us)
2949 {
2950 Some((dns_record, true)) => {
2951 timers.push(dns_record.record.get_record().get_expire_time());
2952 timers.push(dns_record.record.get_record().get_refresh_time());
2953
2954 let ty = dns_record.record.get_type();
2955 let name = dns_record.record.get_name();
2956
2957 if ty == RRType::PTR && dns_record.record.get_record().get_ttl() > 1 {
2959 if self.service_queriers.contains_key(name) {
2960 timers.push(dns_record.record.get_record().get_refresh_time());
2961 }
2962
2963 if let Some(dns_ptr) = dns_record.record.any().downcast_ref::<DnsPointer>()
2965 {
2966 debug!("calling listener with service found: {name}");
2967 call_service_listener(
2968 &self.service_queriers,
2969 name,
2970 ServiceEvent::ServiceFound(
2971 name.to_string(),
2972 dns_ptr.alias().to_string(),
2973 ),
2974 );
2975 changes.push(InstanceChange {
2976 ty,
2977 name: dns_ptr.alias().to_string(),
2978 });
2979 }
2980 } else {
2981 changes.push(InstanceChange {
2982 ty,
2983 name: name.to_string(),
2984 });
2985 }
2986 }
2987 Some((dns_record, false)) => {
2988 timers.push(dns_record.record.get_record().get_expire_time());
2989 timers.push(dns_record.record.get_record().get_refresh_time());
2990 }
2991 _ => {}
2992 }
2993 }
2994
2995 for t in timers {
2997 self.add_timer(t);
2998 }
2999
3000 for change in changes
3002 .iter()
3003 .filter(|change| change.ty == RRType::A || change.ty == RRType::AAAA)
3004 {
3005 let addr_map = self.cache.get_addresses_for_host(&change.name);
3006 for (name, addresses) in addr_map {
3007 call_hostname_resolution_listener(
3008 &self.hostname_resolvers,
3009 &change.name,
3010 HostnameResolutionEvent::AddressesFound(name, addresses),
3011 )
3012 }
3013 }
3014
3015 let mut updated_instances = HashSet::new();
3017 for update in changes {
3018 match update.ty {
3019 RRType::PTR | RRType::SRV | RRType::TXT => {
3020 updated_instances.insert(update.name);
3021 }
3022 RRType::A | RRType::AAAA => {
3023 let instances = self.cache.get_instances_on_host(&update.name);
3024 updated_instances.extend(instances);
3025 }
3026 _ => {}
3027 }
3028 }
3029
3030 self.resolve_updated_instances(&updated_instances);
3031 }
3032
3033 fn conflict_handler(&mut self, msg: &DnsIncoming, if_index: u32) {
3034 let Some(my_intf) = self.my_intfs.get(&if_index) else {
3035 debug!("handle_response: no intf found for index {if_index}");
3036 return;
3037 };
3038
3039 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3040 return;
3041 };
3042
3043 for answer in msg.answers().iter() {
3044 let mut new_records = Vec::new();
3045
3046 let name = answer.get_name();
3047 let Some(probe) = dns_registry.probing.get_mut(name) else {
3048 continue;
3049 };
3050
3051 if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
3053 if let Some(answer_addr) = answer.any().downcast_ref::<DnsAddress>() {
3054 if answer_addr.interface_id.index != if_index {
3055 debug!(
3056 "conflict handler: answer addr {:?} not in the subnet of intf {}",
3057 answer_addr, my_intf.name
3058 );
3059 continue;
3060 }
3061 }
3062
3063 let any_match = probe.records.iter().any(|r| {
3066 r.get_type() == answer.get_type()
3067 && r.get_class() == answer.get_class()
3068 && r.rrdata_match(answer.as_ref())
3069 });
3070 if any_match {
3071 continue; }
3073 }
3074
3075 probe.records.retain(|record| {
3076 if record.get_type() == answer.get_type()
3077 && record.get_class() == answer.get_class()
3078 && !record.rrdata_match(answer.as_ref())
3079 {
3080 debug!(
3081 "found conflict name: '{name}' record: {}: {} PEER: {}",
3082 record.get_type(),
3083 record.rdata_print(),
3084 answer.rdata_print()
3085 );
3086
3087 let mut new_record = record.clone();
3090 let new_name = match record.get_type() {
3091 RRType::A => hostname_change(name),
3092 RRType::AAAA => hostname_change(name),
3093 _ => name_change(name),
3094 };
3095 new_record.get_record_mut().set_new_name(new_name);
3096 new_records.push(new_record);
3097 return false; }
3099
3100 true
3101 });
3102
3103 let create_time = current_time_millis() + fastrand::u64(0..250);
3110
3111 let waiting_services = probe.waiting_services.clone();
3112
3113 for record in new_records {
3114 if dns_registry.update_hostname(name, record.get_name(), create_time) {
3115 self.timers.push(Reverse(create_time));
3116 }
3117
3118 dns_registry.name_changes.insert(
3120 record.get_record().get_original_name().to_string(),
3121 record.get_name().to_string(),
3122 );
3123
3124 let new_probe = match dns_registry.probing.get_mut(record.get_name()) {
3125 Some(p) => p,
3126 None => {
3127 let new_probe = dns_registry
3128 .probing
3129 .entry(record.get_name().to_string())
3130 .or_insert_with(|| {
3131 debug!("conflict handler: new probe of {}", record.get_name());
3132 Probe::new(create_time)
3133 });
3134 self.timers.push(Reverse(new_probe.next_send));
3135 new_probe
3136 }
3137 };
3138
3139 debug!(
3140 "insert record with new name '{}' {} into probe",
3141 record.get_name(),
3142 record.get_type()
3143 );
3144 new_probe.insert_record(record);
3145
3146 new_probe.waiting_services.extend(waiting_services.clone());
3147 }
3148 }
3149 }
3150
3151 fn resolve_updated_instances(&mut self, updated_instances: &HashSet<String>) {
3158 if updated_instances.is_empty() {
3159 return;
3160 }
3161
3162 let mut resolved: HashSet<String> = HashSet::new();
3163 let mut unresolved: HashSet<String> = HashSet::new();
3164 let mut removed_instances = HashMap::new();
3165
3166 let now = current_time_millis();
3167
3168 for (ty_domain, records) in self.cache.all_ptr().iter() {
3169 if !self.service_queriers.contains_key(ty_domain) {
3170 continue;
3172 }
3173
3174 for ptr in records.iter().filter(|r| !r.record.expires_soon(now)) {
3175 let Some(dns_ptr) = ptr.record.any().downcast_ref::<DnsPointer>() else {
3176 continue;
3177 };
3178
3179 let instance = dns_ptr.alias();
3180 if !updated_instances.contains(instance) {
3181 continue;
3182 }
3183
3184 let Ok(resolved_service) = self.resolve_service_from_cache(ty_domain, instance)
3185 else {
3186 continue;
3187 };
3188
3189 debug!("resolve_updated_instances: from cache: {instance}");
3190 if resolved_service.is_valid() {
3191 debug!("call queriers to resolve {instance}");
3192 resolved.insert(instance.to_string());
3193 let event = ServiceEvent::ServiceResolved(Box::new(resolved_service));
3194 call_service_listener(&self.service_queriers, ty_domain, event);
3195 } else {
3196 debug!("Resolved service is not valid: {instance}");
3197 if self.resolved.remove(dns_ptr.alias()) {
3198 removed_instances
3199 .entry(ty_domain.to_string())
3200 .or_insert_with(HashSet::new)
3201 .insert(instance.to_string());
3202 }
3203 unresolved.insert(instance.to_string());
3204 }
3205 }
3206 }
3207
3208 for instance in resolved.drain() {
3209 self.pending_resolves.remove(&instance);
3210 self.resolved.insert(instance);
3211 }
3212
3213 for instance in unresolved.drain() {
3214 self.add_pending_resolve(instance);
3215 }
3216
3217 if !removed_instances.is_empty() {
3218 debug!(
3219 "resolve_updated_instances: removed {}",
3220 &removed_instances.len()
3221 );
3222 self.notify_service_removal(removed_instances);
3223 }
3224 }
3225
3226 fn handle_query(&mut self, msg: DnsIncoming, if_index: u32, querier_addr: SocketAddr) {
3228 let querier_ip = querier_addr.ip();
3229 let is_ipv4 = querier_ip.is_ipv4();
3230 let sock_opt = if is_ipv4 {
3231 &self.ipv4_sock
3232 } else {
3233 &self.ipv6_sock
3234 };
3235 let Some(sock) = sock_opt.as_ref() else {
3236 debug!("handle_query: socket not available for intf {}", if_index);
3237 return;
3238 };
3239
3240 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
3241 let mut delayed = false;
3242
3243 const META_QUERY: &str = "_services._dns-sd._udp.local.";
3246
3247 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3248 debug!("missing dns registry for intf {}", if_index);
3249 return;
3250 };
3251
3252 let Some(intf) = self.my_intfs.get(&if_index) else {
3253 debug!("handle_query: no intf found for index {if_index}");
3254 return;
3255 };
3256
3257 for question in msg.questions().iter() {
3258 let qtype = question.entry_type();
3259 let q_name = question.entry_name();
3260
3261 if qtype == RRType::PTR {
3262 if querier_addr.port() == MDNS_PORT && msg.num_authorities() == 0 {
3266 delayed = true;
3267 }
3268 for service in self.my_services.values() {
3269 if service.get_status(if_index) != ServiceStatus::Announced {
3270 continue;
3271 }
3272
3273 if service.matches_type_or_subtype(q_name) {
3274 out.add_answer_with_additionals(&msg, service, intf, dns_registry, is_ipv4);
3275 } else if q_name == META_QUERY {
3276 let ttl = service.get_other_ttl();
3277 let alias = service.get_type().to_string();
3278 let ptr = DnsPointer::new(q_name, RRType::PTR, CLASS_IN, ttl, alias);
3279 if !out.add_answer(&msg, ptr) {
3280 trace!("answer was not added for meta-query {:?}", &question);
3281 }
3282 }
3283 }
3284 } else {
3285 if qtype == RRType::ANY && msg.num_authorities() > 0 {
3287 if let Some(probe) = dns_registry.probing.get_mut(q_name) {
3288 probe.tiebreaking(&msg, q_name);
3289 }
3290 }
3291
3292 if qtype == RRType::A || qtype == RRType::AAAA || qtype == RRType::ANY {
3293 for service in self.my_services.values() {
3294 if service.get_status(if_index) != ServiceStatus::Announced {
3295 continue;
3296 }
3297
3298 let service_hostname = dns_registry.resolve_name(service.get_hostname());
3299
3300 if service_hostname.to_lowercase() == question.entry_name().to_lowercase() {
3301 let mut intf_addrs: Vec<IpAddr> = Vec::new();
3308 if qtype == RRType::A || qtype == RRType::ANY {
3309 intf_addrs.extend(service.get_addrs_on_my_intf_v4(intf));
3310 }
3311 if qtype == RRType::AAAA || qtype == RRType::ANY {
3312 intf_addrs.extend(service.get_addrs_on_my_intf_v6(intf));
3313 }
3314 if intf_addrs.is_empty()
3315 && (qtype == RRType::A || qtype == RRType::AAAA)
3316 {
3317 let t = match qtype {
3318 RRType::A => "TYPE_A",
3319 RRType::AAAA => "TYPE_AAAA",
3320 _ => "invalid_type",
3321 };
3322 trace!(
3323 "Cannot find valid addrs for {} response on intf {:?}",
3324 t,
3325 &intf
3326 );
3327 continue;
3328 }
3329 for address in intf_addrs {
3330 out.add_answer(
3331 &msg,
3332 DnsAddress::new(
3333 service_hostname,
3334 ip_address_rr_type(&address),
3335 CLASS_IN | CLASS_CACHE_FLUSH,
3336 service.get_host_ttl(),
3337 address,
3338 intf.into(),
3339 ),
3340 );
3341 }
3342 }
3343 }
3344 }
3345
3346 let query_name = q_name.to_lowercase();
3347 let service_opt = self
3348 .my_services
3349 .iter()
3350 .find(|(k, _v)| dns_registry.resolve_name(k.as_str()) == query_name)
3351 .map(|(_, v)| v);
3352
3353 let Some(service) = service_opt else {
3354 continue;
3355 };
3356
3357 if service.get_status(if_index) != ServiceStatus::Announced {
3358 continue;
3359 }
3360
3361 let intf_addrs = if is_ipv4 {
3362 service.get_addrs_on_my_intf_v4(intf)
3363 } else {
3364 service.get_addrs_on_my_intf_v6(intf)
3365 };
3366 if intf_addrs.is_empty() {
3367 debug!(
3368 "Cannot find valid addrs for TYPE_SRV response on intf {:?}",
3369 &intf
3370 );
3371 continue;
3372 }
3373
3374 add_answer_of_service(
3375 &mut out,
3376 &msg,
3377 question.entry_name(),
3378 service,
3379 qtype,
3380 intf_addrs,
3381 );
3382 }
3383 }
3384
3385 if delayed && out.answers_count() > 0 {
3387 out.set_id(msg.id());
3388 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3389 let delay =
3390 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
3391 let next_time = current_time_millis() + delay;
3392 self.delayed_responses.push(DelayedResponse {
3393 next_time,
3394 out,
3395 if_index,
3396 is_ipv4,
3397 });
3398 self.add_timer(next_time);
3399 return;
3400 }
3401
3402 if out.answers_count() > 0 {
3403 out.set_id(msg.id());
3404
3405 let matched_source = intf
3408 .addrs
3409 .iter()
3410 .find(|if_addr| valid_ip_on_intf(&querier_ip, if_addr));
3411
3412 let unicast_dest = if querier_addr.port() != MDNS_PORT {
3420 Some(querier_addr)
3421 } else {
3422 None
3423 };
3424
3425 if unicast_dest.is_some() {
3426 for q in msg.questions() {
3427 out.add_question(q.entry_name(), q.entry_type());
3428 }
3429 out.clear_cache_flush_bits();
3430 } else if msg.num_authorities() == 0 {
3431 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3438 }
3439
3440 if out.answers_count() > 0 {
3441 debug!("sending response on intf {}", &intf.name);
3442 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_dns_outgoing(
3443 &out,
3444 intf,
3445 &sock.pktinfo,
3446 self.port,
3447 matched_source,
3448 unicast_dest,
3449 ) {
3450 let invalid_intf_addr = HashSet::from([intf_addr]);
3451 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3452 }
3453
3454 let if_name = intf.name.clone();
3455
3456 self.increase_counter(Counter::Respond, 1);
3457 self.notify_monitors(DaemonEvent::Respond(if_name));
3458 }
3459 }
3460
3461 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3462 }
3463
3464 fn send_delayed_response(&mut self, resp: DelayedResponse) {
3473 let DelayedResponse {
3474 mut out,
3475 if_index,
3476 is_ipv4,
3477 ..
3478 } = resp;
3479
3480 let sock_opt = if is_ipv4 {
3481 &self.ipv4_sock
3482 } else {
3483 &self.ipv6_sock
3484 };
3485 let Some(sock) = sock_opt.as_ref() else {
3486 debug!("send_delayed_response: socket not available for intf {if_index}");
3487 return;
3488 };
3489
3490 if let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) {
3491 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3492 }
3493 if out.answers_count() == 0 {
3494 return;
3495 }
3496
3497 let Some(intf) = self.my_intfs.get(&if_index) else {
3498 debug!("send_delayed_response: no intf found for index {if_index}");
3499 return;
3500 };
3501
3502 let if_name = intf.name.clone();
3503 debug!("sending delayed response on intf {}", &if_name);
3504 let send_result = send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None);
3505
3506 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_result {
3507 let invalid_intf_addr = HashSet::from([intf_addr]);
3508 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3509 }
3510
3511 self.increase_counter(Counter::Respond, 1);
3512 self.notify_monitors(DaemonEvent::Respond(if_name));
3513 }
3514
3515 fn increase_counter(&mut self, counter: Counter, count: i64) {
3517 let key = counter.to_string();
3518 match self.counters.get_mut(&key) {
3519 Some(v) => *v += count,
3520 None => {
3521 self.counters.insert(key, count);
3522 }
3523 }
3524 }
3525
3526 fn set_counter(&mut self, counter: Counter, count: i64) {
3528 let key = counter.to_string();
3529 self.counters.insert(key, count);
3530 }
3531
3532 fn signal_sock_drain(&self) {
3533 let mut signal_buf = [0; 1024];
3534
3535 while let Ok(sz) = self.signal_sock.recv(&mut signal_buf) {
3537 trace!(
3538 "signal socket recvd: {}",
3539 String::from_utf8_lossy(&signal_buf[0..sz])
3540 );
3541 }
3542 }
3543
3544 fn add_retransmission(&mut self, next_time: u64, command: Command) {
3545 self.retransmissions.push(ReRun { next_time, command });
3546 self.add_timer(next_time);
3547 }
3548
3549 fn notify_service_removal(&self, expired: HashMap<String, HashSet<String>>) {
3552 for (ty_domain, sender) in self.service_queriers.iter() {
3553 if let Some(instances) = expired.get(ty_domain) {
3554 for instance_name in instances {
3555 let event = ServiceEvent::ServiceRemoved(
3556 ty_domain.to_string(),
3557 instance_name.to_string(),
3558 );
3559 match sender.send(event) {
3560 Ok(()) => debug!("notify_service_removal: sent ServiceRemoved to listener of {ty_domain}: {instance_name}"),
3561 Err(e) => debug!("Failed to send event: {}", e),
3562 }
3563 }
3564 }
3565 }
3566 }
3567
3568 fn exec_command(&mut self, command: Command, repeating: bool) {
3572 trace!("exec_command: {:?} repeating: {}", &command, repeating);
3573 match command {
3574 Command::Browse(ty, next_delay, cache_only, listener) => {
3575 self.exec_command_browse(repeating, ty, next_delay, cache_only, listener);
3576 }
3577
3578 Command::ResolveHostname(hostname, next_delay, listener, timeout) => {
3579 self.exec_command_resolve_hostname(
3580 repeating, hostname, next_delay, listener, timeout,
3581 );
3582 }
3583
3584 Command::Register(service_info) => {
3585 self.register_service(*service_info);
3586 self.increase_counter(Counter::Register, 1);
3587 }
3588
3589 Command::RegisterResend(fullname, intf) => {
3590 trace!("register-resend service: {fullname} on {}", &intf);
3591 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
3592 self.exec_command_register_resend(fullname, intf)
3593 {
3594 let invalid_intf_addr = HashSet::from([intf_addr]);
3595 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3596 }
3597 }
3598
3599 Command::Unregister(fullname, resp_s) => {
3600 trace!("unregister service {} repeat {}", &fullname, &repeating);
3601 self.exec_command_unregister(repeating, fullname, resp_s);
3602 }
3603
3604 Command::UnregisterResend(packet, if_index, is_ipv4) => {
3605 self.exec_command_unregister_resend(packet, if_index, is_ipv4);
3606 }
3607
3608 Command::StopBrowse(ty_domain) => self.exec_command_stop_browse(ty_domain),
3609
3610 Command::StopResolveHostname(hostname) => {
3611 self.exec_command_stop_resolve_hostname(hostname.to_lowercase())
3612 }
3613
3614 Command::Resolve(instance, try_count) => self.exec_command_resolve(instance, try_count),
3615
3616 Command::GetMetrics(resp_s) => self.exec_command_get_metrics(resp_s),
3617
3618 Command::GetStatus(resp_s) => match resp_s.send(self.status.clone()) {
3619 Ok(()) => trace!("Sent status to the client"),
3620 Err(e) => debug!("Failed to send status: {}", e),
3621 },
3622
3623 Command::Monitor(resp_s) => {
3624 self.monitors.push(resp_s);
3625 }
3626
3627 Command::SetOption(daemon_opt) => {
3628 self.process_set_option(daemon_opt);
3629 }
3630
3631 Command::GetOption(resp_s) => {
3632 let val = DaemonOptionVal {
3633 _service_name_len_max: self.service_name_len_max,
3634 ip_check_interval: self.ip_check_interval,
3635 };
3636 if let Err(e) = resp_s.send(val) {
3637 debug!("Failed to send options: {}", e);
3638 }
3639 }
3640
3641 Command::Verify(instance_fullname, timeout) => {
3642 self.exec_command_verify(instance_fullname, timeout, repeating);
3643 }
3644
3645 Command::InvalidIntfAddrs(invalid_intf_addrs) => {
3646 for intf_addr in invalid_intf_addrs {
3647 self.del_interface_addr(&intf_addr);
3648 }
3649
3650 self.check_ip_changes();
3651 }
3652
3653 _ => {
3654 debug!("unexpected command: {:?}", &command);
3655 }
3656 }
3657 }
3658
3659 fn exec_command_get_metrics(&mut self, resp_s: Sender<HashMap<String, i64>>) {
3660 self.set_counter(Counter::CachedPTR, self.cache.ptr_count() as i64);
3661 self.set_counter(Counter::CachedSRV, self.cache.srv_count() as i64);
3662 self.set_counter(Counter::CachedAddr, self.cache.addr_count() as i64);
3663 self.set_counter(Counter::CachedTxt, self.cache.txt_count() as i64);
3664 self.set_counter(Counter::CachedNSec, self.cache.nsec_count() as i64);
3665 self.set_counter(Counter::CachedSubtype, self.cache.subtype_count() as i64);
3666 self.set_counter(Counter::Timer, self.timers.len() as i64);
3667
3668 let dns_registry_probe_count: usize = self
3669 .dns_registry_map
3670 .values()
3671 .map(|r| r.probing.len())
3672 .sum();
3673 self.set_counter(Counter::DnsRegistryProbe, dns_registry_probe_count as i64);
3674
3675 let dns_registry_active_count: usize = self
3676 .dns_registry_map
3677 .values()
3678 .map(|r| r.active.values().map(|a| a.len()).sum::<usize>())
3679 .sum();
3680 self.set_counter(Counter::DnsRegistryActive, dns_registry_active_count as i64);
3681
3682 let dns_registry_timer_count: usize = self
3683 .dns_registry_map
3684 .values()
3685 .map(|r| r.new_timers.len())
3686 .sum();
3687 self.set_counter(Counter::DnsRegistryTimer, dns_registry_timer_count as i64);
3688
3689 let dns_registry_name_change_count: usize = self
3690 .dns_registry_map
3691 .values()
3692 .map(|r| r.name_changes.len())
3693 .sum();
3694 self.set_counter(
3695 Counter::DnsRegistryNameChange,
3696 dns_registry_name_change_count as i64,
3697 );
3698
3699 if let Err(e) = resp_s.send(self.counters.clone()) {
3701 debug!("Failed to send metrics: {}", e);
3702 }
3703 }
3704
3705 fn exec_command_browse(
3706 &mut self,
3707 repeating: bool,
3708 ty: String,
3709 next_delay: u32,
3710 cache_only: bool,
3711 listener: Sender<ServiceEvent>,
3712 ) {
3713 let pretty_addrs: Vec<String> = self
3714 .my_intfs
3715 .iter()
3716 .map(|(if_index, itf)| format!("{} ({if_index})", itf.name))
3717 .collect();
3718
3719 if let Err(e) = listener.send(ServiceEvent::SearchStarted(format!(
3720 "{ty} on {} interfaces [{}]",
3721 pretty_addrs.len(),
3722 pretty_addrs.join(", ")
3723 ))) {
3724 debug!(
3725 "Failed to send SearchStarted({})(repeating:{}): {}",
3726 &ty, repeating, e
3727 );
3728 return;
3729 }
3730
3731 let now = current_time_millis();
3732 if !repeating {
3733 self.service_queriers.insert(ty.clone(), listener.clone());
3737
3738 self.query_cache_for_service(&ty, &listener, now);
3740 }
3741
3742 if cache_only {
3743 match listener.send(ServiceEvent::SearchStopped(ty.clone())) {
3745 Ok(()) => debug!("SearchStopped sent for {}", &ty),
3746 Err(e) => debug!("Failed to send SearchStopped: {}", e),
3747 }
3748 return;
3749 }
3750
3751 if !repeating {
3752 let jitter =
3754 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3755 self.add_retransmission(now + jitter, Command::Browse(ty, 1, cache_only, listener));
3756 return;
3757 }
3758
3759 self.send_query(&ty, RRType::PTR);
3760 self.increase_counter(Counter::Browse, 1);
3761
3762 let next_time = now + (next_delay * 1000) as u64;
3763 let max_delay = 60 * 60;
3764 let delay = cmp::min(next_delay * 2, max_delay);
3765 self.add_retransmission(next_time, Command::Browse(ty, delay, cache_only, listener));
3766 }
3767
3768 fn exec_command_resolve_hostname(
3769 &mut self,
3770 repeating: bool,
3771 hostname: String,
3772 next_delay: u32,
3773 listener: Sender<HostnameResolutionEvent>,
3774 timeout: Option<u64>,
3775 ) {
3776 let addr_list: Vec<_> = self.my_intfs.iter().collect();
3777 if let Err(e) = listener.send(HostnameResolutionEvent::SearchStarted(format!(
3778 "{} on addrs {:?}",
3779 &hostname, &addr_list
3780 ))) {
3781 debug!(
3782 "Failed to send ResolveStarted({})(repeating:{}): {}",
3783 &hostname, repeating, e
3784 );
3785 return;
3786 }
3787 let now = current_time_millis();
3788 if !repeating {
3789 self.add_hostname_resolver(hostname.to_owned(), listener.clone(), timeout);
3790 self.query_cache_for_hostname(&hostname, listener.clone());
3792
3793 let jitter =
3795 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3796 self.add_retransmission(
3797 now + jitter,
3798 Command::ResolveHostname(hostname, 1, listener, None),
3799 );
3800 return;
3801 }
3802
3803 self.send_query_vec(&[(&hostname, RRType::A), (&hostname, RRType::AAAA)]);
3804 self.increase_counter(Counter::ResolveHostname, 1);
3805
3806 let next_time = now + u64::from(next_delay) * 1000;
3807 let max_delay = 60 * 60;
3808 let delay = cmp::min(next_delay * 2, max_delay);
3809
3810 if self
3812 .hostname_resolvers
3813 .get(&hostname)
3814 .and_then(|(_sender, timeout)| *timeout)
3815 .map(|timeout| next_time < timeout)
3816 .unwrap_or(true)
3817 {
3818 self.add_retransmission(
3819 next_time,
3820 Command::ResolveHostname(hostname, delay, listener, None),
3821 );
3822 }
3823 }
3824
3825 fn exec_command_resolve(&mut self, instance: String, try_count: u16) {
3826 let pending_query = self.query_unresolved(&instance);
3827 let max_try = 3;
3828 if pending_query && try_count < max_try {
3829 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
3832 self.add_retransmission(next_time, Command::Resolve(instance, try_count + 1));
3833 }
3834 }
3835
3836 fn exec_command_unregister(
3837 &mut self,
3838 repeating: bool,
3839 fullname: String,
3840 resp_s: Sender<UnregisterStatus>,
3841 ) {
3842 let response = match self.my_services.remove_entry(&fullname) {
3843 None => {
3844 debug!("unregister: cannot find such service {}", &fullname);
3845 UnregisterStatus::NotFound
3846 }
3847 Some((_k, info)) => {
3848 let mut timers = Vec::new();
3849
3850 for (if_index, intf) in self.my_intfs.iter() {
3851 if let Some(sock) = self.ipv4_sock.as_ref() {
3852 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
3853 if !repeating && !packet.is_empty() {
3855 let next_time = current_time_millis() + 120;
3856 self.retransmissions.push(ReRun {
3857 next_time,
3858 command: Command::UnregisterResend(packet, *if_index, true),
3859 });
3860 timers.push(next_time);
3861 }
3862 }
3863
3864 if let Some(sock) = self.ipv6_sock.as_ref() {
3866 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
3867 if !repeating && !packet.is_empty() {
3868 let next_time = current_time_millis() + 120;
3869 self.retransmissions.push(ReRun {
3870 next_time,
3871 command: Command::UnregisterResend(packet, *if_index, false),
3872 });
3873 timers.push(next_time);
3874 }
3875 }
3876 }
3877
3878 for t in timers {
3879 self.add_timer(t);
3880 }
3881
3882 self.increase_counter(Counter::Unregister, 1);
3883 UnregisterStatus::OK
3884 }
3885 };
3886 if let Err(e) = resp_s.send(response) {
3887 debug!("unregister: failed to send response: {}", e);
3888 }
3889 }
3890
3891 fn exec_command_unregister_resend(&mut self, packet: Vec<u8>, if_index: u32, is_ipv4: bool) {
3892 let Some(intf) = self.my_intfs.get(&if_index) else {
3893 return;
3894 };
3895 let sock_opt = if is_ipv4 {
3896 &self.ipv4_sock
3897 } else {
3898 &self.ipv6_sock
3899 };
3900 let Some(sock) = sock_opt else {
3901 return;
3902 };
3903
3904 let if_addr = if is_ipv4 {
3905 match intf.next_ifaddr_v4() {
3906 Some(addr) => addr,
3907 None => return,
3908 }
3909 } else {
3910 match intf.next_ifaddr_v6() {
3911 Some(addr) => addr,
3912 None => return,
3913 }
3914 };
3915
3916 debug!("UnregisterResend from {:?}", if_addr);
3917 multicast_on_intf(
3918 &packet[..],
3919 &intf.name,
3920 intf.index,
3921 if_addr,
3922 &sock.pktinfo,
3923 self.port,
3924 );
3925
3926 self.increase_counter(Counter::UnregisterResend, 1);
3927 }
3928
3929 fn exec_command_stop_browse(&mut self, ty_domain: String) {
3930 match self.service_queriers.remove_entry(&ty_domain) {
3931 None => debug!("StopBrowse: cannot find querier for {}", &ty_domain),
3932 Some((ty, sender)) => {
3933 trace!("StopBrowse: removed queryer for {}", &ty);
3935 let mut i = 0;
3936 while i < self.retransmissions.len() {
3937 if let Command::Browse(t, _, _, _) = &self.retransmissions[i].command {
3938 if t == &ty {
3939 self.retransmissions.remove(i);
3940 trace!("StopBrowse: removed retransmission for {}", &ty);
3941 continue;
3942 }
3943 }
3944 i += 1;
3945 }
3946
3947 self.cache.remove_service_type(&ty_domain);
3949
3950 match sender.send(ServiceEvent::SearchStopped(ty_domain)) {
3952 Ok(()) => trace!("Sent SearchStopped to the listener"),
3953 Err(e) => debug!("Failed to send SearchStopped: {}", e),
3954 }
3955 }
3956 }
3957 }
3958
3959 fn exec_command_stop_resolve_hostname(&mut self, hostname: String) {
3960 if let Some((host, (sender, _timeout))) = self.hostname_resolvers.remove_entry(&hostname) {
3961 trace!("StopResolve: removed queryer for {}", &host);
3963 let mut i = 0;
3964 while i < self.retransmissions.len() {
3965 if let Command::Resolve(t, _) = &self.retransmissions[i].command {
3966 if t == &host {
3967 self.retransmissions.remove(i);
3968 trace!("StopResolve: removed retransmission for {}", &host);
3969 continue;
3970 }
3971 }
3972 i += 1;
3973 }
3974
3975 match sender.send(HostnameResolutionEvent::SearchStopped(hostname)) {
3977 Ok(()) => trace!("Sent SearchStopped to the listener"),
3978 Err(e) => debug!("Failed to send SearchStopped: {}", e),
3979 }
3980 }
3981 }
3982
3983 fn exec_command_register_resend(&mut self, fullname: String, if_index: u32) -> MyResult<()> {
3984 let Some(info) = self.my_services.get_mut(&fullname) else {
3985 trace!("announce: cannot find such service {}", &fullname);
3986 return Ok(());
3987 };
3988
3989 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3990 return Ok(());
3991 };
3992
3993 let Some(intf) = self.my_intfs.get(&if_index) else {
3994 return Ok(());
3995 };
3996
3997 let announced_v4 = if let Some(sock) = self.ipv4_sock.as_ref() {
3998 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
3999 } else {
4000 false
4001 };
4002 let announced_v6 = if let Some(sock) = self.ipv6_sock.as_ref() {
4003 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
4004 } else {
4005 false
4006 };
4007
4008 if announced_v4 || announced_v6 {
4009 let hostname = dns_registry.resolve_name(info.get_hostname());
4010 let service_name = dns_registry.resolve_name(&fullname).to_string();
4011
4012 debug!("resend: announce service {service_name} on {}", intf.name);
4013
4014 notify_monitors(
4015 &mut self.monitors,
4016 DaemonEvent::Announce(service_name, format!("{}:{}", hostname, &intf.name)),
4017 );
4018 info.set_status(if_index, ServiceStatus::Announced);
4019 } else {
4020 debug!("register-resend should not fail");
4021 }
4022
4023 self.increase_counter(Counter::RegisterResend, 1);
4024 Ok(())
4025 }
4026
4027 fn exec_command_verify(&mut self, instance: String, timeout: Duration, repeating: bool) {
4028 let now = current_time_millis();
4038 let expire_at = if repeating {
4039 None
4040 } else {
4041 Some(now + timeout.as_millis() as u64)
4042 };
4043
4044 let record_vec = self.cache.service_verify_queries(&instance, expire_at);
4046
4047 if !record_vec.is_empty() {
4048 let query_vec: Vec<(&str, RRType)> = record_vec
4049 .iter()
4050 .map(|(record, rr_type)| (record.as_str(), *rr_type))
4051 .collect();
4052 self.send_query_vec(&query_vec);
4053
4054 if let Some(new_expire) = expire_at {
4055 self.add_timer(new_expire); self.add_retransmission(now + 1000, Command::Verify(instance, timeout));
4059 }
4060 }
4061 }
4062
4063 fn refresh_active_services(&mut self) {
4065 let mut query_ptr_count = 0;
4066 let mut query_srv_count = 0;
4067 let mut new_timers = HashSet::new();
4068 let mut query_addr_count = 0;
4069
4070 for (ty_domain, _sender) in self.service_queriers.iter() {
4071 let refreshed_timers = self.cache.refresh_due_ptr(ty_domain);
4072 if !refreshed_timers.is_empty() {
4073 trace!("sending refresh query for PTR: {}", ty_domain);
4074 self.send_query(ty_domain, RRType::PTR);
4075 query_ptr_count += 1;
4076 new_timers.extend(refreshed_timers);
4077 }
4078
4079 let (instances, timers) = self.cache.refresh_due_srv_txt(ty_domain);
4080 for (instance, types) in instances {
4081 trace!("sending refresh query for: {}", &instance);
4082 let query_vec = types
4083 .into_iter()
4084 .map(|ty| (instance.as_str(), ty))
4085 .collect::<Vec<_>>();
4086 self.send_query_vec(&query_vec);
4087 query_srv_count += 1;
4088 }
4089 new_timers.extend(timers);
4090 let (hostnames, timers) = self.cache.refresh_due_hosts(ty_domain);
4091 for hostname in hostnames.iter() {
4092 trace!("sending refresh queries for A and AAAA: {}", hostname);
4093 self.send_query_vec(&[(hostname, RRType::A), (hostname, RRType::AAAA)]);
4094 query_addr_count += 2;
4095 }
4096 new_timers.extend(timers);
4097 }
4098
4099 for timer in new_timers {
4100 self.add_timer(timer);
4101 }
4102
4103 self.increase_counter(Counter::CacheRefreshPTR, query_ptr_count);
4104 self.increase_counter(Counter::CacheRefreshSrvTxt, query_srv_count);
4105 self.increase_counter(Counter::CacheRefreshAddr, query_addr_count);
4106 }
4107}
4108
4109fn add_answer_of_service(
4111 out: &mut DnsOutgoing,
4112 msg: &DnsIncoming,
4113 entry_name: &str,
4114 service: &ServiceInfo,
4115 qtype: RRType,
4116 intf_addrs: Vec<IpAddr>,
4117) {
4118 if qtype == RRType::SRV || qtype == RRType::ANY {
4119 out.add_answer(
4120 msg,
4121 DnsSrv::new(
4122 entry_name,
4123 CLASS_IN | CLASS_CACHE_FLUSH,
4124 service.get_host_ttl(),
4125 service.get_priority(),
4126 service.get_weight(),
4127 service.get_port(),
4128 service.get_hostname().to_string(),
4129 ),
4130 );
4131 }
4132
4133 if qtype == RRType::TXT || qtype == RRType::ANY {
4134 out.add_answer(
4135 msg,
4136 DnsTxt::new(
4137 entry_name,
4138 CLASS_IN | CLASS_CACHE_FLUSH,
4139 service.get_other_ttl(),
4140 service.generate_txt(),
4141 ),
4142 );
4143 }
4144
4145 if qtype == RRType::SRV {
4146 for address in intf_addrs {
4147 out.add_additional_answer(DnsAddress::new(
4148 service.get_hostname(),
4149 ip_address_rr_type(&address),
4150 CLASS_IN | CLASS_CACHE_FLUSH,
4151 service.get_host_ttl(),
4152 address,
4153 InterfaceId::default(),
4154 ));
4155 }
4156 }
4157}
4158
4159#[derive(Clone, Debug)]
4162#[non_exhaustive]
4163pub enum ServiceEvent {
4164 SearchStarted(String),
4166
4167 ServiceFound(String, String),
4169
4170 ServiceResolved(Box<ResolvedService>),
4172
4173 ServiceRemoved(String, String),
4175
4176 SearchStopped(String),
4178}
4179
4180#[derive(Clone, Debug)]
4183#[non_exhaustive]
4184pub enum HostnameResolutionEvent {
4185 SearchStarted(String),
4187 AddressesFound(String, HashSet<ScopedIp>),
4189 AddressesRemoved(String, HashSet<ScopedIp>),
4191 SearchTimeout(String),
4193 SearchStopped(String),
4195}
4196
4197#[derive(Clone, Debug)]
4200#[non_exhaustive]
4201pub enum DaemonEvent {
4202 Announce(String, String),
4204
4205 Error(Error),
4207
4208 IpAdd(IpAddr),
4210
4211 IpDel(IpAddr),
4213
4214 NameChange(DnsNameChange),
4217
4218 Respond(String),
4220}
4221
4222#[derive(Clone, Debug)]
4225pub struct DnsNameChange {
4226 pub original: String,
4228
4229 pub new_name: String,
4239
4240 pub rr_type: RRType,
4242
4243 pub intf_name: String,
4245}
4246
4247#[derive(Debug)]
4249enum Command {
4250 Browse(String, u32, bool, Sender<ServiceEvent>),
4252
4253 ResolveHostname(String, u32, Sender<HostnameResolutionEvent>, Option<u64>), Register(Box<ServiceInfo>),
4258
4259 Unregister(String, Sender<UnregisterStatus>), RegisterResend(String, u32), UnregisterResend(Vec<u8>, u32, bool), StopBrowse(String), StopResolveHostname(String), Resolve(String, u16), GetMetrics(Sender<Metrics>),
4280
4281 GetStatus(Sender<DaemonStatus>),
4283
4284 Monitor(Sender<DaemonEvent>),
4286
4287 SetOption(DaemonOption),
4288
4289 GetOption(Sender<DaemonOptionVal>),
4290
4291 Verify(String, Duration),
4296
4297 InvalidIntfAddrs(HashSet<Interface>),
4299
4300 Exit(Sender<DaemonStatus>),
4301}
4302
4303impl fmt::Display for Command {
4304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4305 match self {
4306 Self::Browse(_, _, _, _) => write!(f, "Command Browse"),
4307 Self::ResolveHostname(_, _, _, _) => write!(f, "Command ResolveHostname"),
4308 Self::Exit(_) => write!(f, "Command Exit"),
4309 Self::GetStatus(_) => write!(f, "Command GetStatus"),
4310 Self::GetMetrics(_) => write!(f, "Command GetMetrics"),
4311 Self::Monitor(_) => write!(f, "Command Monitor"),
4312 Self::Register(_) => write!(f, "Command Register"),
4313 Self::RegisterResend(_, _) => write!(f, "Command RegisterResend"),
4314 Self::SetOption(_) => write!(f, "Command SetOption"),
4315 Self::GetOption(_) => write!(f, "Command GetOption"),
4316 Self::StopBrowse(_) => write!(f, "Command StopBrowse"),
4317 Self::StopResolveHostname(_) => write!(f, "Command StopResolveHostname"),
4318 Self::Unregister(_, _) => write!(f, "Command Unregister"),
4319 Self::UnregisterResend(_, _, _) => write!(f, "Command UnregisterResend"),
4320 Self::Resolve(_, _) => write!(f, "Command Resolve"),
4321 Self::Verify(_, _) => write!(f, "Command VerifyResource"),
4322 Self::InvalidIntfAddrs(_) => write!(f, "Command InvalidIntfAddrs"),
4323 }
4324 }
4325}
4326
4327struct DaemonOptionVal {
4328 _service_name_len_max: u8,
4329 ip_check_interval: u64,
4330}
4331
4332#[derive(Debug)]
4333enum DaemonOption {
4334 ServiceNameLenMax(u8),
4335 IpCheckInterval(u64),
4336 EnableInterface(Vec<IfKind>),
4337 DisableInterface(Vec<IfKind>),
4338 MulticastLoopV4(bool),
4339 MulticastLoopV6(bool),
4340 AcceptUnsolicited(bool),
4341 IncludeAppleP2P(bool),
4342 #[cfg(test)]
4343 TestDownInterface(String),
4344 #[cfg(test)]
4345 TestUpInterface(String),
4346}
4347
4348const DOMAIN_LEN: usize = "._tcp.local.".len();
4350
4351fn check_service_name_length(ty_domain: &str, limit: u8) -> Result<()> {
4353 if ty_domain.len() <= DOMAIN_LEN + 1 {
4354 return Err(e_fmt!("Service type name cannot be empty: {}", ty_domain));
4356 }
4357
4358 let service_name_len = ty_domain.len() - DOMAIN_LEN - 1; if service_name_len > limit as usize {
4360 return Err(e_fmt!("Service name length must be <= {} bytes", limit));
4361 }
4362 Ok(())
4363}
4364
4365fn check_domain_suffix(name: &str) -> Result<()> {
4367 if !(name.ends_with("._tcp.local.") || name.ends_with("._udp.local.")) {
4368 return Err(e_fmt!(
4369 "mDNS service {} must end with '._tcp.local.' or '._udp.local.'",
4370 name
4371 ));
4372 }
4373
4374 Ok(())
4375}
4376
4377fn check_service_name(fullname: &str) -> Result<()> {
4385 check_domain_suffix(fullname)?;
4386
4387 let remaining: Vec<&str> = fullname[..fullname.len() - DOMAIN_LEN].split('.').collect();
4388 let name = remaining.last().ok_or_else(|| e_fmt!("No service name"))?;
4389
4390 if &name[0..1] != "_" {
4391 return Err(e_fmt!("Service name must start with '_'"));
4392 }
4393
4394 let name = &name[1..];
4395
4396 if name.contains("--") {
4397 return Err(e_fmt!("Service name must not contain '--'"));
4398 }
4399
4400 if name.starts_with('-') || name.ends_with('-') {
4401 return Err(e_fmt!("Service name (%s) may not start or end with '-'"));
4402 }
4403
4404 let ascii_count = name.chars().filter(|c| c.is_ascii_alphabetic()).count();
4405 if ascii_count < 1 {
4406 return Err(e_fmt!(
4407 "Service name must contain at least one letter (eg: 'A-Za-z')"
4408 ));
4409 }
4410
4411 Ok(())
4412}
4413
4414fn check_hostname(hostname: &str) -> Result<()> {
4416 if !hostname.ends_with(".local.") {
4417 return Err(e_fmt!("Hostname must end with '.local.': {hostname}"));
4418 }
4419
4420 if hostname == ".local." {
4421 return Err(e_fmt!(
4422 "The part of the hostname before '.local.' cannot be empty"
4423 ));
4424 }
4425
4426 if hostname.len() > 255 {
4427 return Err(e_fmt!("Hostname length must be <= 255 bytes"));
4428 }
4429
4430 Ok(())
4431}
4432
4433fn call_service_listener(
4434 listeners_map: &HashMap<String, Sender<ServiceEvent>>,
4435 ty_domain: &str,
4436 event: ServiceEvent,
4437) {
4438 if let Some(listener) = listeners_map.get(ty_domain) {
4439 match listener.send(event) {
4440 Ok(()) => trace!("Sent event to listener successfully"),
4441 Err(e) => debug!("Failed to send event: {}", e),
4442 }
4443 }
4444}
4445
4446fn call_hostname_resolution_listener(
4447 listeners_map: &HashMap<String, (Sender<HostnameResolutionEvent>, Option<u64>)>,
4448 hostname: &str,
4449 event: HostnameResolutionEvent,
4450) {
4451 let hostname_lower = hostname.to_lowercase();
4452 if let Some(listener) = listeners_map.get(&hostname_lower).map(|(l, _)| l) {
4453 match listener.send(event) {
4454 Ok(()) => trace!("Sent event to listener successfully"),
4455 Err(e) => debug!("Failed to send event: {}", e),
4456 }
4457 }
4458}
4459
4460fn my_ip_interfaces(with_loopback: bool) -> Vec<Interface> {
4464 my_ip_interfaces_inner(with_loopback, false)
4465}
4466
4467fn my_ip_interfaces_inner(with_loopback: bool, with_apple_p2p: bool) -> Vec<Interface> {
4468 if_addrs::get_if_addrs()
4469 .unwrap_or_default()
4470 .into_iter()
4471 .filter(|i| {
4472 i.is_oper_up()
4473 && !i.is_p2p()
4474 && (!i.is_loopback() || with_loopback)
4475 && (with_apple_p2p || !is_apple_p2p_by_name(&i.name))
4476 })
4477 .collect()
4478}
4479
4480fn is_apple_p2p_by_name(name: &str) -> bool {
4483 let p2p_prefixes = ["awdl", "llw"];
4484 p2p_prefixes.iter().any(|prefix| name.starts_with(prefix))
4485}
4486
4487fn send_dns_outgoing(
4490 out: &DnsOutgoing,
4491 my_intf: &MyIntf,
4492 sock: &PktInfoUdpSocket,
4493 port: u16,
4494 source: Option<&IfAddr>,
4495 unicast_dest: Option<SocketAddr>,
4496) -> MyResult<Vec<Vec<u8>>> {
4497 let if_name = &my_intf.name;
4498
4499 let if_addr = match source {
4500 Some(addr) => addr,
4501 None => {
4502 if sock.domain() == Domain::IPV4 {
4503 match my_intf.next_ifaddr_v4() {
4504 Some(addr) => addr,
4505 None => return Ok(vec![]),
4506 }
4507 } else {
4508 match my_intf.next_ifaddr_v6() {
4509 Some(addr) => addr,
4510 None => return Ok(vec![]),
4511 }
4512 }
4513 }
4514 };
4515
4516 send_dns_outgoing_impl(
4517 out,
4518 if_name,
4519 my_intf.index,
4520 if_addr,
4521 sock,
4522 port,
4523 unicast_dest,
4524 )
4525}
4526
4527fn send_dns_outgoing_impl(
4529 out: &DnsOutgoing,
4530 if_name: &str,
4531 if_index: u32,
4532 if_addr: &IfAddr,
4533 sock: &PktInfoUdpSocket,
4534 port: u16,
4535 unicast_dest: Option<SocketAddr>,
4536) -> MyResult<Vec<Vec<u8>>> {
4537 let qtype = if out.is_query() {
4538 "query"
4539 } else {
4540 if out.answers_count() == 0 && out.additionals().is_empty() {
4541 return Ok(vec![]); }
4543 "response"
4544 };
4545 trace!(
4546 "send {}: {} questions {} answers {} authorities {} additional",
4547 qtype,
4548 out.questions().len(),
4549 out.answers_count(),
4550 out.authorities().len(),
4551 out.additionals().len()
4552 );
4553
4554 match if_addr.ip() {
4555 IpAddr::V4(ipv4) => {
4556 if let Err(e) = sock.set_multicast_if_v4(&ipv4) {
4557 debug!(
4558 "send_dns_outgoing: failed to set multicast interface for IPv4 {}: {}",
4559 ipv4, e
4560 );
4561 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4563 let intf_addr = Interface {
4564 name: if_name.to_string(),
4565 addr: if_addr.clone(),
4566 index: Some(if_index),
4567 oper_status: if_addrs::IfOperStatus::Down,
4568 is_p2p: false,
4569 #[cfg(windows)]
4570 adapter_name: String::new(),
4571 };
4572 return Err(InternalError::IntfAddrInvalid(intf_addr));
4573 }
4574 return Ok(vec![]); }
4576 }
4577 IpAddr::V6(ipv6) => {
4578 if let Err(e) = sock.set_multicast_if_v6(if_index) {
4579 debug!(
4580 "send_dns_outgoing: failed to set multicast interface for IPv6 {}: {}",
4581 ipv6, e
4582 );
4583 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4585 let intf_addr = Interface {
4586 name: if_name.to_string(),
4587 addr: if_addr.clone(),
4588 index: Some(if_index),
4589 oper_status: if_addrs::IfOperStatus::Down,
4590 is_p2p: false,
4591 #[cfg(windows)]
4592 adapter_name: String::new(),
4593 };
4594 return Err(InternalError::IntfAddrInvalid(intf_addr));
4595 }
4596 return Ok(vec![]); }
4598 }
4599 }
4600
4601 let packet_list = out.to_data_on_wire();
4602 for packet in packet_list.iter() {
4603 match unicast_dest {
4604 Some(dest) => unicast_on_intf(packet, if_name, dest, sock),
4605 None => multicast_on_intf(packet, if_name, if_index, if_addr, sock, port),
4606 }
4607 }
4608 Ok(packet_list)
4609}
4610
4611fn unicast_on_intf(packet: &[u8], if_name: &str, dest: SocketAddr, socket: &PktInfoUdpSocket) {
4614 if packet.len() > MAX_MSG_ABSOLUTE {
4615 debug!("Drop over-sized packet ({})", packet.len());
4616 return;
4617 }
4618
4619 let sock_addr = dest.into();
4620 match socket.send_to(packet, &sock_addr) {
4621 Ok(sz) => trace!(
4622 "sent unicast {} bytes on interface {} to {}",
4623 sz,
4624 if_name,
4625 dest
4626 ),
4627 Err(e) => trace!(
4628 "Failed to send unicast to {} via {:?}: {}",
4629 dest,
4630 &if_name,
4631 e
4632 ),
4633 }
4634}
4635
4636fn multicast_on_intf(
4638 packet: &[u8],
4639 if_name: &str,
4640 if_index: u32,
4641 if_addr: &IfAddr,
4642 socket: &PktInfoUdpSocket,
4643 port: u16,
4644) {
4645 if packet.len() > MAX_MSG_ABSOLUTE {
4646 debug!("Drop over-sized packet ({})", packet.len());
4647 return;
4648 }
4649
4650 let addr: SocketAddr = match if_addr {
4651 if_addrs::IfAddr::V4(_) => SocketAddrV4::new(GROUP_ADDR_V4, port).into(),
4652 if_addrs::IfAddr::V6(_) => {
4653 let mut sock = SocketAddrV6::new(GROUP_ADDR_V6, port, 0, 0);
4654 sock.set_scope_id(if_index); sock.into()
4656 }
4657 };
4658
4659 let sock_addr = addr.into();
4661 match socket.send_to(packet, &sock_addr) {
4662 Ok(sz) => trace!(
4663 "sent out {} bytes on interface {} (idx {}) addr {}",
4664 sz,
4665 if_name,
4666 if_index,
4667 if_addr.ip()
4668 ),
4669 Err(e) => trace!("Failed to send to {} via {:?}: {}", addr, &if_name, e),
4670 }
4671}
4672
4673fn valid_instance_name(name: &str) -> bool {
4677 name.split('.').count() >= 5
4678}
4679
4680fn notify_monitors(monitors: &mut Vec<Sender<DaemonEvent>>, event: DaemonEvent) {
4681 monitors.retain(|sender| {
4682 if let Err(e) = sender.try_send(event.clone()) {
4683 debug!("notify_monitors: try_send: {}", &e);
4684 if matches!(e, TrySendError::Disconnected(_)) {
4685 return false; }
4687 }
4688 true
4689 });
4690}
4691
4692fn prepare_announce(
4695 info: &ServiceInfo,
4696 intf: &MyIntf,
4697 dns_registry: &mut DnsRegistry,
4698 is_ipv4: bool,
4699) -> Option<DnsOutgoing> {
4700 let intf_addrs = if is_ipv4 {
4701 info.get_addrs_on_my_intf_v4(intf)
4702 } else {
4703 info.get_addrs_on_my_intf_v6(intf)
4704 };
4705
4706 if intf_addrs.is_empty() {
4707 debug!(
4708 "prepare_announce (ipv4: {is_ipv4}): no valid addrs on interface {}",
4709 &intf.name
4710 );
4711 return None;
4712 }
4713
4714 let service_fullname = dns_registry.resolve_name(info.get_fullname());
4716
4717 debug!(
4718 "prepare to announce service {service_fullname} on {:?}",
4719 &intf_addrs
4720 );
4721
4722 let mut probing_count = 0;
4723 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
4724 let create_time = current_time_millis() + fastrand::u64(0..250);
4725
4726 out.add_answer_at_time(
4727 DnsPointer::new(
4728 info.get_type(),
4729 RRType::PTR,
4730 CLASS_IN,
4731 info.get_other_ttl(),
4732 service_fullname.to_string(),
4733 ),
4734 0,
4735 );
4736
4737 if let Some(sub) = info.get_subtype() {
4738 trace!("Adding subdomain {}", sub);
4739 out.add_answer_at_time(
4740 DnsPointer::new(
4741 sub,
4742 RRType::PTR,
4743 CLASS_IN,
4744 info.get_other_ttl(),
4745 service_fullname.to_string(),
4746 ),
4747 0,
4748 );
4749 }
4750
4751 let hostname = dns_registry.resolve_name(info.get_hostname()).to_string();
4753
4754 let mut srv = DnsSrv::new(
4755 info.get_fullname(),
4756 CLASS_IN | CLASS_CACHE_FLUSH,
4757 info.get_host_ttl(),
4758 info.get_priority(),
4759 info.get_weight(),
4760 info.get_port(),
4761 hostname,
4762 );
4763
4764 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4765 srv.get_record_mut().set_new_name(new_name.to_string());
4766 }
4767
4768 if !info.requires_probe()
4769 || dns_registry.is_probing_done(&srv, info.get_fullname(), create_time)
4770 {
4771 out.add_answer_at_time(srv, 0);
4772 } else {
4773 probing_count += 1;
4774 }
4775
4776 let mut txt = DnsTxt::new(
4779 info.get_fullname(),
4780 CLASS_IN | CLASS_CACHE_FLUSH,
4781 info.get_other_ttl(),
4782 info.generate_txt(),
4783 );
4784
4785 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4786 txt.get_record_mut().set_new_name(new_name.to_string());
4787 }
4788
4789 if !info.requires_probe()
4790 || dns_registry.is_probing_done(&txt, info.get_fullname(), create_time)
4791 {
4792 out.add_answer_at_time(txt, 0);
4793 } else {
4794 probing_count += 1;
4795 }
4796
4797 let hostname = info.get_hostname();
4800 for address in intf_addrs {
4801 let mut dns_addr = DnsAddress::new(
4802 hostname,
4803 ip_address_rr_type(&address),
4804 CLASS_IN | CLASS_CACHE_FLUSH,
4805 info.get_host_ttl(),
4806 address,
4807 intf.into(),
4808 );
4809
4810 if let Some(new_name) = dns_registry.name_changes.get(hostname) {
4811 dns_addr.get_record_mut().set_new_name(new_name.to_string());
4812 }
4813
4814 if !info.requires_probe()
4815 || dns_registry.is_probing_done(&dns_addr, info.get_fullname(), create_time)
4816 {
4817 out.add_answer_at_time(dns_addr, 0);
4818 } else {
4819 probing_count += 1;
4820 }
4821 }
4822
4823 if probing_count > 0 {
4824 return None;
4825 }
4826
4827 Some(out)
4828}
4829
4830fn announce_service_on_intf(
4833 dns_registry: &mut DnsRegistry,
4834 info: &ServiceInfo,
4835 intf: &MyIntf,
4836 sock: &PktInfoUdpSocket,
4837 port: u16,
4838) -> MyResult<bool> {
4839 let is_ipv4 = sock.domain() == Domain::IPV4;
4840 if let Some(mut out) = prepare_announce(info, intf, dns_registry, is_ipv4) {
4841 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
4844 if out.answers_count() > 0 {
4845 let _ = send_dns_outgoing(&out, intf, sock, port, None, None)?;
4846 }
4847 return Ok(true);
4848 }
4849
4850 Ok(false)
4851}
4852
4853fn name_change(original: &str) -> String {
4861 let mut parts: Vec<_> = original.split('.').collect();
4862 let Some(first_part) = parts.get_mut(0) else {
4863 return format!("{original} (2)");
4864 };
4865
4866 let mut new_name = format!("{first_part} (2)");
4867
4868 if let Some(paren_pos) = first_part.rfind(" (") {
4870 if let Some(end_paren) = first_part[paren_pos..].find(')') {
4872 let absolute_end_pos = paren_pos + end_paren;
4873 if absolute_end_pos == first_part.len() - 1 {
4875 let num_start = paren_pos + 2; if let Ok(number) = first_part[num_start..absolute_end_pos].parse::<u32>() {
4878 let base_name = &first_part[..paren_pos];
4879 new_name = format!("{} ({})", base_name, number + 1)
4880 }
4881 }
4882 }
4883 }
4884
4885 *first_part = &new_name;
4886 parts.join(".")
4887}
4888
4889fn hostname_change(original: &str) -> String {
4897 let mut parts: Vec<_> = original.split('.').collect();
4898 let Some(first_part) = parts.get_mut(0) else {
4899 return format!("{original}-2");
4900 };
4901
4902 let mut new_name = format!("{first_part}-2");
4903
4904 if let Some(hyphen_pos) = first_part.rfind('-') {
4906 if let Ok(number) = first_part[hyphen_pos + 1..].parse::<u32>() {
4908 let base_name = &first_part[..hyphen_pos];
4909 new_name = format!("{}-{}", base_name, number + 1);
4910 }
4911 }
4912
4913 *first_part = &new_name;
4914 parts.join(".")
4915}
4916
4917fn check_probing(
4920 dns_registry: &mut DnsRegistry,
4921 timers: &mut BinaryHeap<Reverse<u64>>,
4922 now: u64,
4923) -> (DnsOutgoing, Vec<String>) {
4924 let mut expired_probes = Vec::new();
4925 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
4926
4927 for (name, probe) in dns_registry.probing.iter_mut() {
4928 if now >= probe.next_send {
4929 if probe.expired(now) {
4930 expired_probes.push(name.clone());
4932 } else {
4933 out.add_question(name, RRType::ANY);
4934
4935 for record in probe.records.iter() {
4943 out.add_authority(record.clone());
4944 }
4945
4946 probe.update_next_send(now);
4947
4948 timers.push(Reverse(probe.next_send));
4950 }
4951 }
4952 }
4953
4954 (out, expired_probes)
4955}
4956
4957fn handle_expired_probes(
4962 expired_probes: Vec<String>,
4963 intf_name: &str,
4964 dns_registry: &mut DnsRegistry,
4965 monitors: &mut Vec<Sender<DaemonEvent>>,
4966) -> HashSet<String> {
4967 let mut waiting_services = HashSet::new();
4968
4969 for name in expired_probes {
4970 let Some(probe) = dns_registry.probing.remove(&name) else {
4971 continue;
4972 };
4973
4974 for record in probe.records.iter() {
4976 if let Some(new_name) = record.get_record().get_new_name() {
4977 dns_registry
4978 .name_changes
4979 .insert(name.clone(), new_name.to_string());
4980
4981 let event = DnsNameChange {
4982 original: record.get_record().get_original_name().to_string(),
4983 new_name: new_name.to_string(),
4984 rr_type: record.get_type(),
4985 intf_name: intf_name.to_string(),
4986 };
4987 debug!("Name change event: {:?}", &event);
4988 notify_monitors(monitors, DaemonEvent::NameChange(event));
4989 }
4990 }
4991
4992 debug!(
4994 "probe of '{name}' finished: move {} records to active. ({} waiting services)",
4995 probe.records.len(),
4996 probe.waiting_services.len(),
4997 );
4998
4999 if !probe.records.is_empty() {
5001 match dns_registry.active.get_mut(&name) {
5002 Some(records) => {
5003 records.extend(probe.records);
5004 }
5005 None => {
5006 dns_registry.active.insert(name, probe.records);
5007 }
5008 }
5009
5010 waiting_services.extend(probe.waiting_services);
5011 }
5012 }
5013
5014 waiting_services
5015}
5016
5017fn resolve_addr_to_index(if_kind: IfKind, interfaces: &[Interface]) -> IfKind {
5019 if let IfKind::Addr(addr) = &if_kind {
5020 if let Some(intf) = interfaces.iter().find(|intf| &intf.ip() == addr) {
5021 let if_index = intf.index.unwrap_or(0);
5022 return if addr.is_ipv4() {
5023 IfKind::IndexV4(if_index)
5024 } else {
5025 IfKind::IndexV6(if_index)
5026 };
5027 }
5028 }
5029 if_kind
5030}
5031
5032#[cfg(test)]
5033mod tests {
5034 use super::{
5035 _new_socket_bind, check_domain_suffix, check_service_name_length, hostname_change,
5036 my_ip_interfaces, name_change, send_dns_outgoing_impl, valid_instance_name,
5037 valid_ip_on_intf, DaemonEvent, HostnameResolutionEvent, MyIntf, ServiceDaemon,
5038 ServiceEvent, ServiceInfo, GROUP_ADDR_V4, INITIAL_QUERY_DELAY_MAX_MILLIS,
5039 INITIAL_QUERY_DELAY_MIN_MILLIS, MDNS_PORT, SHARED_RESPONSE_DELAY_MAX_MILLIS,
5040 SHARED_RESPONSE_DELAY_MIN_MILLIS,
5041 };
5042 use crate::{
5043 dns_parser::{
5044 DnsEntryExt, DnsIncoming, DnsOutgoing, DnsPointer, InterfaceId, RRType, ScopedIp,
5045 CLASS_IN, FLAGS_AA, FLAGS_QR_QUERY, FLAGS_QR_RESPONSE,
5046 },
5047 service_daemon::{add_answer_of_service, check_hostname},
5048 };
5049 use if_addrs::{IfAddr, Ifv4Addr};
5050 use std::{
5051 collections::HashSet,
5052 net::{IpAddr, Ipv4Addr, UdpSocket},
5053 time::{Duration, Instant, SystemTime},
5054 };
5055 use test_log::test;
5056
5057 #[test]
5058 fn test_response_source_ifaddr_match() {
5059 let ifaddr_a = IfAddr::V4(Ifv4Addr {
5063 ip: Ipv4Addr::new(192, 168, 1, 148),
5064 netmask: Ipv4Addr::new(255, 255, 255, 0),
5065 broadcast: None,
5066 prefixlen: 24,
5067 });
5068 let ifaddr_b = IfAddr::V4(Ifv4Addr {
5069 ip: Ipv4Addr::new(10, 238, 0, 51),
5070 netmask: Ipv4Addr::new(255, 255, 255, 0),
5071 broadcast: None,
5072 prefixlen: 24,
5073 });
5074
5075 let intf = MyIntf {
5076 name: "dummy0".to_string(),
5077 index: 1,
5078 addrs: HashSet::from([ifaddr_a.clone(), ifaddr_b.clone()]),
5079 };
5080
5081 let pick = |querier: IpAddr| -> Option<IfAddr> {
5082 intf.addrs
5083 .iter()
5084 .find(|a| valid_ip_on_intf(&querier, a))
5085 .cloned()
5086 };
5087
5088 assert_eq!(
5089 pick(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 2))),
5090 Some(ifaddr_a)
5091 );
5092 assert_eq!(
5093 pick(IpAddr::V4(Ipv4Addr::new(10, 238, 0, 99))),
5094 Some(ifaddr_b)
5095 );
5096 assert_eq!(pick(IpAddr::V4(Ipv4Addr::new(172, 16, 0, 1))), None);
5098 }
5099
5100 #[test]
5101 fn test_instance_name() {
5102 assert!(valid_instance_name("my-laser._printer._tcp.local."));
5103 assert!(valid_instance_name("my-laser.._printer._tcp.local."));
5104 assert!(!valid_instance_name("_printer._tcp.local."));
5105 }
5106
5107 #[test]
5108 fn test_legacy_unicast_response() {
5109 let intf_ip = match my_ip_interfaces(false)
5120 .into_iter()
5121 .find_map(|intf| match intf.ip() {
5122 IpAddr::V4(ip) => Some(ip),
5123 IpAddr::V6(_) => None,
5124 }) {
5125 Some(ip) => ip,
5126 None => {
5127 println!("No IPv4 interface available; skipping test.");
5128 return;
5129 }
5130 };
5131
5132 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5134 let unique = SystemTime::now()
5135 .duration_since(SystemTime::UNIX_EPOCH)
5136 .unwrap()
5137 .as_micros();
5138 let hostname = format!("legacy-unicast-test-{unique}.local.");
5139 let service_info = ServiceInfo::new(
5140 "_legacy-uni._udp.local.",
5141 "test_instance",
5142 &hostname,
5143 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5144 5353, None,
5146 )
5147 .expect("invalid service info");
5148 daemon.register(service_info).expect("register service");
5149
5150 let querier = UdpSocket::bind((intf_ip, 0)).expect("bind querier socket");
5154 querier
5155 .set_multicast_loop_v4(true)
5156 .expect("enable multicast loopback");
5157 querier
5158 .set_read_timeout(Some(Duration::from_millis(500)))
5159 .expect("set read timeout");
5160 assert_ne!(
5161 querier.local_addr().unwrap().port(),
5162 MDNS_PORT,
5163 "querier must use an ephemeral (non-5353) source port"
5164 );
5165
5166 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5168 query.add_question(&hostname, RRType::A);
5169 let query_packet = query
5170 .to_data_on_wire()
5171 .pop()
5172 .expect("query serialized to one packet");
5173
5174 let if_id = InterfaceId {
5175 name: "test".to_string(),
5176 index: 0,
5177 };
5178
5179 let deadline = Instant::now() + Duration::from_secs(8);
5182 let mut response = None;
5183 'outer: while Instant::now() < deadline {
5184 querier
5185 .send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5186 .expect("send query");
5187
5188 let mut buf = [0u8; 1500];
5191 while let Ok((len, from)) = querier.recv_from(&mut buf) {
5192 let Ok(msg) = DnsIncoming::new(buf[..len].to_vec(), if_id.clone()) else {
5193 continue;
5194 };
5195 if msg.is_response()
5196 && msg
5197 .answers()
5198 .iter()
5199 .any(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5200 {
5201 response = Some((msg, from));
5202 break 'outer;
5203 }
5204 }
5205 }
5206
5207 let (msg, from) = response.expect(
5208 "expected a unicast response to the legacy query; \
5209 a multicast-only reply would never reach this un-joined socket",
5210 );
5211
5212 assert_eq!(
5214 from.port(),
5215 MDNS_PORT,
5216 "response should originate from the mDNS port"
5217 );
5218
5219 assert!(
5221 msg.questions()
5222 .iter()
5223 .any(|q| q.entry_name().eq_ignore_ascii_case(&hostname)),
5224 "legacy unicast response must echo the question section"
5225 );
5226
5227 let answer = msg
5230 .answers()
5231 .iter()
5232 .find(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5233 .expect("response contains an answer for our hostname");
5234 assert_eq!(
5235 answer.get_type(),
5236 RRType::A,
5237 "an A query should be answered with an A record"
5238 );
5239 assert!(
5240 !answer.get_cache_flush(),
5241 "legacy unicast responses must clear the cache-flush bit"
5242 );
5243
5244 daemon.shutdown().unwrap();
5245 }
5246
5247 #[test]
5248 fn test_shared_response_delay_bounds() {
5249 assert_eq!(SHARED_RESPONSE_DELAY_MIN_MILLIS, 10);
5254 assert_eq!(SHARED_RESPONSE_DELAY_MAX_MILLIS, 50);
5255 for _ in 0..10_000 {
5256 let d =
5257 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
5258 assert!(
5259 (SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS).contains(&d),
5260 "delay {} ms is outside the configured {}-{} ms range",
5261 d,
5262 SHARED_RESPONSE_DELAY_MIN_MILLIS,
5263 SHARED_RESPONSE_DELAY_MAX_MILLIS
5264 );
5265 }
5266 }
5267
5268 #[test]
5269 fn test_initial_query_delayed() {
5270 use socket2::{Domain, Protocol, Socket, Type};
5277
5278 let (intf, intf_ip) = match my_ip_interfaces(false)
5279 .into_iter()
5280 .find_map(|intf| match intf.ip() {
5281 IpAddr::V4(ip) if !ip.is_loopback() => Some((intf, ip)),
5282 _ => None,
5283 }) {
5284 Some(pair) => pair,
5285 None => {
5286 println!("No IPv4 interface available; skipping test.");
5287 return;
5288 }
5289 };
5290 let interface_id = InterfaceId::from(&intf);
5291
5292 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5296 sock.set_reuse_address(true).unwrap();
5297 #[cfg(unix)]
5298 sock.set_reuse_port(true).unwrap();
5299 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5300 .unwrap();
5301 sock.join_multicast_v4(&GROUP_ADDR_V4, &intf_ip).unwrap();
5302 sock.set_read_timeout(Some(Duration::from_millis(200)))
5303 .unwrap();
5304 let sock: UdpSocket = sock.into();
5305
5306 let unique = SystemTime::now()
5308 .duration_since(SystemTime::UNIX_EPOCH)
5309 .unwrap()
5310 .as_micros()
5311 % 1_000_000_000;
5312 let service_type = format!("_qd{unique}._udp.local.");
5313
5314 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5315
5316 let sent_at = Instant::now();
5317 let _browse = daemon.browse(&service_type).expect("browse");
5318
5319 let deadline = Instant::now() + Duration::from_secs(2);
5322 let mut buf = [0u8; 2048];
5323 let mut measured = None;
5324 while Instant::now() < deadline {
5325 let n = match sock.recv_from(&mut buf) {
5326 Ok((n, _)) => n,
5327 Err(_) => continue, };
5329 let Ok(msg) = DnsIncoming::new(buf[..n].to_vec(), interface_id.clone()) else {
5330 continue;
5331 };
5332 if msg.is_query()
5333 && msg
5334 .questions()
5335 .iter()
5336 .any(|q| q.entry_name() == service_type)
5337 {
5338 measured = Some(sent_at.elapsed());
5339 break;
5340 }
5341 }
5342
5343 daemon.shutdown().unwrap();
5344
5345 let elapsed = measured.expect("expected the daemon to send a PTR query for our browse");
5346 let tolerance = Duration::from_millis(2);
5347 assert!(
5348 elapsed + tolerance >= Duration::from_millis(INITIAL_QUERY_DELAY_MIN_MILLIS),
5349 "first browse query was sent after only {:?}; the first query of a series must be \
5350 delayed (10-50 ms window), not sent immediately",
5351 elapsed
5352 );
5353
5354 let scheduling_slack = Duration::from_millis(50);
5359 assert!(
5360 elapsed <= Duration::from_millis(INITIAL_QUERY_DELAY_MAX_MILLIS) + scheduling_slack,
5361 "first browse query was sent after {:?}, beyond the {}-{} ms jitter window (plus slack)",
5362 elapsed,
5363 INITIAL_QUERY_DELAY_MIN_MILLIS,
5364 INITIAL_QUERY_DELAY_MAX_MILLIS
5365 );
5366 }
5367
5368 #[test]
5369 fn test_shared_ptr_response_delayed() {
5370 use socket2::{Domain, Protocol, Socket, Type};
5377
5378 let intf_ip = match my_ip_interfaces(false)
5379 .into_iter()
5380 .find_map(|intf| match intf.ip() {
5381 IpAddr::V4(ip) if !ip.is_loopback() => Some(ip),
5382 _ => None,
5383 }) {
5384 Some(ip) => ip,
5385 None => {
5386 println!("No IPv4 interface available; skipping test.");
5387 return;
5388 }
5389 };
5390
5391 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5392 let monitor = daemon.monitor().expect("monitor daemon events");
5393
5394 let unique = SystemTime::now()
5397 .duration_since(SystemTime::UNIX_EPOCH)
5398 .unwrap()
5399 .as_micros()
5400 % 1_000_000_000;
5401 let service_type = format!("_sd{unique}._udp.local.");
5402 let hostname = format!("sd{unique}.local.");
5403 let service_info = ServiceInfo::new(
5404 &service_type,
5405 "test_instance",
5406 &hostname,
5407 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5408 5353,
5409 None,
5410 )
5411 .expect("invalid service info");
5412 daemon.register(service_info).expect("register service");
5413
5414 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5418 sock.set_reuse_address(true).unwrap();
5419 #[cfg(unix)]
5420 sock.set_reuse_port(true).unwrap();
5421 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5422 .unwrap();
5423 sock.set_multicast_if_v4(&intf_ip).unwrap();
5424 sock.set_multicast_loop_v4(true).unwrap();
5426 let sock: UdpSocket = sock.into();
5427
5428 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5430 query.add_question(&service_type, RRType::PTR);
5431 let query_packet = query.to_data_on_wire().pop().expect("one packet");
5432
5433 std::thread::sleep(Duration::from_secs(3));
5437
5438 let deadline = Instant::now() + Duration::from_secs(8);
5442 let mut measured = None;
5443 while Instant::now() < deadline {
5444 while monitor.try_recv().is_ok() {}
5447
5448 let sent_at = Instant::now();
5449 sock.send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5450 .expect("send query");
5451
5452 let attempt_deadline = sent_at + Duration::from_millis(700);
5455 loop {
5456 let remaining = attempt_deadline.saturating_duration_since(Instant::now());
5457 if remaining.is_zero() {
5458 break;
5459 }
5460 match monitor.recv_timeout(remaining) {
5461 Ok(DaemonEvent::Respond(_)) => {
5462 measured = Some(sent_at.elapsed());
5463 break;
5464 }
5465 Ok(_) => continue, Err(_) => break, }
5468 }
5469 if measured.is_some() {
5470 break;
5471 }
5472 }
5473
5474 let elapsed =
5475 measured.expect("expected the daemon to respond to our PTR query within the deadline");
5476 assert!(
5477 elapsed >= Duration::from_millis(8),
5478 "PTR response was sent after only {:?}; a shared-record response must be \
5479 delayed (10-50 ms window), not sent immediately",
5480 elapsed
5481 );
5482 assert!(
5483 elapsed <= Duration::from_millis(600),
5484 "PTR response was sent after {:?}; expected within the 10-50 ms delay window",
5485 elapsed
5486 );
5487
5488 daemon.shutdown().unwrap();
5489 }
5490
5491 #[test]
5492 fn test_check_service_name_length() {
5493 let result = check_service_name_length("_tcp", 100);
5494 assert!(result.is_err());
5495 if let Err(e) = result {
5496 println!("{}", e);
5497 }
5498 }
5499
5500 #[test]
5501 fn test_check_hostname() {
5502 for hostname in &[
5504 "my_host.local.",
5505 &("A".repeat(255 - ".local.".len()) + ".local."),
5506 ] {
5507 let result = check_hostname(hostname);
5508 assert!(result.is_ok());
5509 }
5510
5511 for hostname in &[
5513 "my_host.local",
5514 ".local.",
5515 &("A".repeat(256 - ".local.".len()) + ".local."),
5516 ] {
5517 let result = check_hostname(hostname);
5518 assert!(result.is_err());
5519 if let Err(e) = result {
5520 println!("{}", e);
5521 }
5522 }
5523 }
5524
5525 #[test]
5526 fn test_check_domain_suffix() {
5527 assert!(check_domain_suffix("_missing_dot._tcp.local").is_err());
5528 assert!(check_domain_suffix("_missing_bar.tcp.local.").is_err());
5529 assert!(check_domain_suffix("_mis_spell._tpp.local.").is_err());
5530 assert!(check_domain_suffix("_mis_spell._upp.local.").is_err());
5531 assert!(check_domain_suffix("_has_dot._tcp.local.").is_ok());
5532 assert!(check_domain_suffix("_goodname._udp.local.").is_ok());
5533 }
5534
5535 #[test]
5536 fn test_service_with_temporarily_invalidated_ptr() {
5537 let d = ServiceDaemon::new().expect("Failed to create daemon");
5539
5540 let service = "_test_inval_ptr._udp.local.";
5541 let host_name = "my_host_tmp_invalidated_ptr.local.";
5542 let intfs: Vec<_> = my_ip_interfaces(false);
5543 let intf_ips: Vec<_> = intfs.iter().map(|intf| intf.ip()).collect();
5544 let port = 5201;
5545 let my_service =
5546 ServiceInfo::new(service, "my_instance", host_name, &intf_ips[..], port, None)
5547 .expect("invalid service info")
5548 .enable_addr_auto();
5549 let result = d.register(my_service.clone());
5550 assert!(result.is_ok());
5551
5552 let browse_chan = d.browse(service).unwrap();
5554 let timeout = Duration::from_secs(2);
5555 let mut resolved = false;
5556
5557 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5558 match event {
5559 ServiceEvent::ServiceResolved(info) => {
5560 resolved = true;
5561 println!("Resolved a service of {}", &info.fullname);
5562 break;
5563 }
5564 e => {
5565 println!("Received event {:?}", e);
5566 }
5567 }
5568 }
5569
5570 assert!(resolved);
5571
5572 println!("Stopping browse of {}", service);
5573 d.stop_browse(service).unwrap();
5576
5577 let mut stopped = false;
5582 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5583 match event {
5584 ServiceEvent::SearchStopped(_) => {
5585 stopped = true;
5586 println!("Stopped browsing service");
5587 break;
5588 }
5589 e => {
5593 println!("Received event {:?}", e);
5594 }
5595 }
5596 }
5597
5598 assert!(stopped);
5599
5600 let invalidate_ptr_packet = DnsPointer::new(
5602 my_service.get_type(),
5603 RRType::PTR,
5604 CLASS_IN,
5605 0,
5606 my_service.get_fullname().to_string(),
5607 );
5608
5609 let mut packet_buffer = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
5610 packet_buffer.add_additional_answer(invalidate_ptr_packet);
5611
5612 for intf in intfs {
5613 let sock = _new_socket_bind(&intf, true).unwrap();
5614 send_dns_outgoing_impl(
5615 &packet_buffer,
5616 &intf.name,
5617 intf.index.unwrap_or(0),
5618 &intf.addr,
5619 &sock.pktinfo,
5620 MDNS_PORT,
5621 None,
5622 )
5623 .unwrap();
5624 }
5625
5626 println!(
5627 "Sent PTR record invalidation. Starting second browse for {}",
5628 service
5629 );
5630
5631 let browse_chan = d.browse(service).unwrap();
5633
5634 resolved = false;
5635 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5636 match event {
5637 ServiceEvent::ServiceResolved(info) => {
5638 resolved = true;
5639 println!("Resolved a service of {}", &info.fullname);
5640 break;
5641 }
5642 e => {
5643 println!("Received event {:?}", e);
5644 }
5645 }
5646 }
5647
5648 assert!(resolved);
5649 d.shutdown().unwrap();
5650 }
5651
5652 #[test]
5653 fn test_expired_srv() {
5654 let service_type = "_expired-srv._udp.local.";
5656 let instance = "test_instance";
5657 let host_name = "expired_srv_host.local.";
5658 let mut my_service = ServiceInfo::new(service_type, instance, host_name, "", 5023, None)
5659 .unwrap()
5660 .enable_addr_auto();
5661 let new_ttl = 3; my_service._set_host_ttl(new_ttl);
5666
5667 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
5669 let result = mdns_server.register(my_service);
5670 assert!(result.is_ok());
5671
5672 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
5673 let browse_chan = mdns_client.browse(service_type).unwrap();
5674 let timeout = Duration::from_secs(2);
5675 let mut resolved = false;
5676
5677 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5678 if let ServiceEvent::ServiceResolved(info) = event {
5679 resolved = true;
5680 println!("Resolved a service of {}", &info.fullname);
5681 break;
5682 }
5683 }
5684
5685 assert!(resolved);
5686
5687 mdns_server.shutdown().unwrap();
5689
5690 let expire_timeout = Duration::from_secs(new_ttl as u64);
5692 while let Ok(event) = browse_chan.recv_timeout(expire_timeout) {
5693 if let ServiceEvent::ServiceRemoved(service_type, full_name) = event {
5694 println!("Service removed: {}: {}", &service_type, &full_name);
5695 break;
5696 }
5697 }
5698 }
5699
5700 #[test]
5701 fn test_hostname_resolution_address_removed() {
5702 let server = ServiceDaemon::new().expect("Failed to create server");
5704 let hostname = "addr_remove_host._tcp.local.";
5705 let service_ip_addr: ScopedIp = my_ip_interfaces(false)
5706 .iter()
5707 .find(|iface| iface.ip().is_ipv4())
5708 .map(|iface| iface.into())
5709 .unwrap();
5710
5711 let mut my_service = ServiceInfo::new(
5712 "_host_res_test._tcp.local.",
5713 "my_instance",
5714 hostname,
5715 service_ip_addr.to_ip_addr(),
5716 1234,
5717 None,
5718 )
5719 .expect("invalid service info");
5720
5721 let addr_ttl = 2;
5723 my_service._set_host_ttl(addr_ttl); server.register(my_service).unwrap();
5726
5727 let client = ServiceDaemon::new().expect("Failed to create client");
5729 let event_receiver = client.resolve_hostname(hostname, None).unwrap();
5730 let resolved = loop {
5731 match event_receiver.recv() {
5732 Ok(HostnameResolutionEvent::AddressesFound(found_hostname, addresses)) => {
5733 assert!(found_hostname == hostname);
5734 assert!(addresses.contains(&service_ip_addr));
5735 println!("address found: {:?}", &addresses);
5736 break true;
5737 }
5738 Ok(HostnameResolutionEvent::SearchStopped(_)) => break false,
5739 Ok(_event) => {}
5740 Err(_) => break false,
5741 }
5742 };
5743
5744 assert!(resolved);
5745
5746 server.shutdown().unwrap();
5748
5749 let timeout = Duration::from_secs(addr_ttl as u64 + 1);
5751 let removed = loop {
5752 match event_receiver.recv_timeout(timeout) {
5753 Ok(HostnameResolutionEvent::AddressesRemoved(removed_host, addresses)) => {
5754 assert!(removed_host == hostname);
5755 assert!(addresses.contains(&service_ip_addr));
5756
5757 println!(
5758 "address removed: hostname: {} addresses: {:?}",
5759 &hostname, &addresses
5760 );
5761 break true;
5762 }
5763 Ok(_event) => {}
5764 Err(_) => {
5765 break false;
5766 }
5767 }
5768 };
5769
5770 assert!(removed);
5771
5772 client.shutdown().unwrap();
5773 }
5774
5775 #[test]
5776 fn test_refresh_ptr() {
5777 let service_type = "_refresh-ptr._udp.local.";
5779 let instance = "test_instance";
5780 let host_name = "refresh_ptr_host.local.";
5781 let service_ip_addr = my_ip_interfaces(false)
5782 .iter()
5783 .find(|iface| iface.ip().is_ipv4())
5784 .map(|iface| iface.ip())
5785 .unwrap();
5786
5787 let mut my_service = ServiceInfo::new(
5788 service_type,
5789 instance,
5790 host_name,
5791 service_ip_addr,
5792 5023,
5793 None,
5794 )
5795 .unwrap();
5796
5797 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
5799
5800 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
5802 let result = mdns_server.register(my_service);
5803 assert!(result.is_ok());
5804
5805 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
5806 let browse_chan = mdns_client.browse(service_type).unwrap();
5807 let timeout = Duration::from_millis(1500); let mut resolved = false;
5809
5810 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5812 if let ServiceEvent::ServiceResolved(info) = event {
5813 resolved = true;
5814 println!("Resolved a service of {}", &info.fullname);
5815 break;
5816 }
5817 }
5818
5819 assert!(resolved);
5820
5821 let timeout = Duration::from_millis(new_ttl as u64 * 1000 * 90 / 100);
5823 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5824 println!("event: {:?}", &event);
5825 }
5826
5827 let metrics_chan = mdns_client.get_metrics().unwrap();
5829 let metrics = metrics_chan.recv_timeout(timeout).unwrap();
5830 let ptr_refresh_counter = metrics["cache-refresh-ptr"];
5831 assert_eq!(ptr_refresh_counter, 1);
5832 let srvtxt_refresh_counter = metrics["cache-refresh-srv-txt"];
5833 assert_eq!(srvtxt_refresh_counter, 1);
5834
5835 mdns_server.shutdown().unwrap();
5837 mdns_client.shutdown().unwrap();
5838 }
5839
5840 #[test]
5841 fn test_name_change() {
5842 assert_eq!(name_change("foo.local."), "foo (2).local.");
5843 assert_eq!(name_change("foo (2).local."), "foo (3).local.");
5844 assert_eq!(name_change("foo (9).local."), "foo (10).local.");
5845 assert_eq!(name_change("foo"), "foo (2)");
5846 assert_eq!(name_change("foo (2)"), "foo (3)");
5847 assert_eq!(name_change(""), " (2)");
5848
5849 assert_eq!(name_change("foo (abc)"), "foo (abc) (2)"); assert_eq!(name_change("foo (2"), "foo (2 (2)"); assert_eq!(name_change("foo (2) extra"), "foo (2) extra (2)"); }
5854
5855 #[test]
5856 fn test_hostname_change() {
5857 assert_eq!(hostname_change("foo.local."), "foo-2.local.");
5858 assert_eq!(hostname_change("foo"), "foo-2");
5859 assert_eq!(hostname_change("foo-2.local."), "foo-3.local.");
5860 assert_eq!(hostname_change("foo-9"), "foo-10");
5861 assert_eq!(hostname_change("test-42.domain."), "test-43.domain.");
5862 }
5863
5864 #[test]
5865 fn test_add_answer_txt_ttl() {
5866 let service_type = "_test_add_answer._udp.local.";
5868 let instance = "test_instance";
5869 let host_name = "add_answer_host.local.";
5870 let service_intf = my_ip_interfaces(false)
5871 .into_iter()
5872 .find(|iface| iface.ip().is_ipv4())
5873 .unwrap();
5874 let service_ip_addr = service_intf.ip();
5875 let my_service = ServiceInfo::new(
5876 service_type,
5877 instance,
5878 host_name,
5879 service_ip_addr,
5880 5023,
5881 None,
5882 )
5883 .unwrap();
5884
5885 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
5887
5888 let mut dummy_data = out.to_data_on_wire();
5890 let interface_id = InterfaceId::from(&service_intf);
5891 let incoming = DnsIncoming::new(dummy_data.pop().unwrap(), interface_id).unwrap();
5892
5893 let if_addrs = vec![service_intf.ip()];
5895 add_answer_of_service(
5896 &mut out,
5897 &incoming,
5898 instance,
5899 &my_service,
5900 RRType::TXT,
5901 if_addrs,
5902 );
5903
5904 assert!(
5906 out.answers_count() > 0,
5907 "No answers added to the outgoing message"
5908 );
5909
5910 let answer = out._answers().first().unwrap();
5912 assert_eq!(answer.0.get_type(), RRType::TXT);
5913
5914 assert_eq!(answer.0.get_record().get_ttl(), my_service.get_other_ttl());
5916 }
5917
5918 #[test]
5919 fn test_interface_flip() {
5920 let ty_domain = "_intf-flip._udp.local.";
5922 let host_name = "intf_flip.local.";
5923 let now = SystemTime::now()
5924 .duration_since(SystemTime::UNIX_EPOCH)
5925 .unwrap();
5926 let instance_name = now.as_micros().to_string(); let port = 5200;
5928
5929 let (ip_addr1, intf_name) = my_ip_interfaces(false)
5931 .iter()
5932 .find(|iface| iface.ip().is_ipv4())
5933 .map(|iface| (iface.ip(), iface.name.clone()))
5934 .unwrap();
5935
5936 println!("Using interface {} with IP {}", intf_name, ip_addr1);
5937
5938 let service1 = ServiceInfo::new(ty_domain, &instance_name, host_name, ip_addr1, port, None)
5940 .expect("valid service info");
5941 let server1 = ServiceDaemon::new().expect("failed to start server");
5942 server1
5943 .register(service1)
5944 .expect("Failed to register service1");
5945
5946 std::thread::sleep(Duration::from_secs(2));
5948
5949 let client = ServiceDaemon::new().expect("failed to start client");
5951
5952 let receiver = client.browse(ty_domain).unwrap();
5953
5954 let timeout = Duration::from_secs(3);
5955 let mut got_data = false;
5956
5957 while let Ok(event) = receiver.recv_timeout(timeout) {
5958 if let ServiceEvent::ServiceResolved(_) = event {
5959 println!("Received ServiceResolved event");
5960 got_data = true;
5961 break;
5962 }
5963 }
5964
5965 assert!(got_data, "Should receive ServiceResolved event");
5966
5967 client.set_ip_check_interval(1).unwrap();
5969
5970 println!("Shutting down interface {}", &intf_name);
5972 client.test_down_interface(&intf_name).unwrap();
5973
5974 let mut got_removed = false;
5975
5976 while let Ok(event) = receiver.recv_timeout(timeout) {
5977 if let ServiceEvent::ServiceRemoved(ty_domain, instance) = event {
5978 got_removed = true;
5979 println!("removed: {ty_domain} : {instance}");
5980 break;
5981 }
5982 }
5983 assert!(got_removed, "Should receive ServiceRemoved event");
5984
5985 println!("Bringing up interface {}", &intf_name);
5986 client.test_up_interface(&intf_name).unwrap();
5987 let mut got_data = false;
5988 while let Ok(event) = receiver.recv_timeout(timeout) {
5989 if let ServiceEvent::ServiceResolved(resolved) = event {
5990 got_data = true;
5991 println!("Received ServiceResolved: {:?}", resolved);
5992 break;
5993 }
5994 }
5995 assert!(
5996 got_data,
5997 "Should receive ServiceResolved event after interface is back up"
5998 );
5999
6000 server1.shutdown().unwrap();
6001 client.shutdown().unwrap();
6002 }
6003
6004 #[test]
6005 fn test_cache_only() {
6006 let service_type = "_cache_only._udp.local.";
6008 let instance = "test_instance";
6009 let host_name = "cache_only_host.local.";
6010 let service_ip_addr = my_ip_interfaces(false)
6011 .iter()
6012 .find(|iface| iface.ip().is_ipv4())
6013 .map(|iface| iface.ip())
6014 .unwrap();
6015
6016 let mut my_service = ServiceInfo::new(
6017 service_type,
6018 instance,
6019 host_name,
6020 service_ip_addr,
6021 5023,
6022 None,
6023 )
6024 .unwrap();
6025
6026 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
6028
6029 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6030
6031 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6034 std::thread::sleep(Duration::from_secs(2));
6035
6036 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6038 let result = mdns_server.register(my_service);
6039 assert!(result.is_ok());
6040
6041 let timeout = Duration::from_millis(1500); let mut resolved = false;
6043
6044 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6046 if let ServiceEvent::ServiceResolved(info) = event {
6047 resolved = true;
6048 println!("Resolved a service of {}", &info.get_fullname());
6049 break;
6050 }
6051 }
6052
6053 assert!(resolved);
6054
6055 mdns_server.shutdown().unwrap();
6057 mdns_client.shutdown().unwrap();
6058 }
6059
6060 #[test]
6061 fn test_cache_only_unsolicited() {
6062 let service_type = "_c_unsolicit._udp.local.";
6063 let instance = "test_instance";
6064 let host_name = "c_unsolicit_host.local.";
6065 let service_ip_addr = my_ip_interfaces(false)
6066 .iter()
6067 .find(|iface| iface.ip().is_ipv4())
6068 .map(|iface| iface.ip())
6069 .unwrap();
6070
6071 let my_service = ServiceInfo::new(
6072 service_type,
6073 instance,
6074 host_name,
6075 service_ip_addr,
6076 5023,
6077 None,
6078 )
6079 .unwrap();
6080
6081 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6083 let result = mdns_server.register(my_service);
6084 assert!(result.is_ok());
6085
6086 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6087 mdns_client.accept_unsolicited(true).unwrap();
6088
6089 std::thread::sleep(Duration::from_secs(2));
6092 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6093 let timeout = Duration::from_millis(1500); let mut resolved = false;
6095
6096 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6098 if let ServiceEvent::ServiceResolved(info) = event {
6099 resolved = true;
6100 println!("Resolved a service of {}", &info.get_fullname());
6101 break;
6102 }
6103 }
6104
6105 assert!(resolved);
6106
6107 mdns_server.shutdown().unwrap();
6109 mdns_client.shutdown().unwrap();
6110 }
6111
6112 #[test]
6113 fn test_custom_port_isolation() {
6114 let service_type = "_custom_port._udp.local.";
6119 let instance_custom = "custom_port_instance";
6120 let instance_default = "default_port_instance";
6121 let host_name = "custom_port_host.local.";
6122
6123 let service_ip_addr = my_ip_interfaces(false)
6124 .iter()
6125 .find(|iface| iface.ip().is_ipv4())
6126 .map(|iface| iface.ip())
6127 .expect("Test requires an IPv4 interface");
6128
6129 let service_custom = ServiceInfo::new(
6131 service_type,
6132 instance_custom,
6133 host_name,
6134 service_ip_addr,
6135 8080,
6136 None,
6137 )
6138 .unwrap();
6139
6140 let service_default = ServiceInfo::new(
6142 service_type,
6143 instance_default,
6144 host_name,
6145 service_ip_addr,
6146 8081,
6147 None,
6148 )
6149 .unwrap();
6150
6151 let custom_port = 5454u16;
6153 let server_custom =
6154 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port server");
6155 let client_custom =
6156 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port client");
6157
6158 let server_default = ServiceDaemon::new().expect("Failed to create default port server");
6160
6161 server_custom
6163 .register(service_custom.clone())
6164 .expect("Failed to register custom port service");
6165
6166 server_default
6168 .register(service_default.clone())
6169 .expect("Failed to register default port service");
6170
6171 let browse_custom = client_custom
6173 .browse(service_type)
6174 .expect("Failed to browse on custom port");
6175
6176 let timeout = Duration::from_secs(3);
6177 let mut found_custom = false;
6178 let mut found_default_on_custom = false;
6179
6180 while let Ok(event) = browse_custom.recv_timeout(timeout) {
6182 if let ServiceEvent::ServiceResolved(info) = event {
6183 println!(
6184 "Custom port client resolved: {} on port {}",
6185 info.get_fullname(),
6186 info.get_port()
6187 );
6188 if info.get_fullname().starts_with(instance_custom) {
6189 found_custom = true;
6190 assert_eq!(info.get_port(), 8080);
6191 }
6192 if info.get_fullname().starts_with(instance_default) {
6193 found_default_on_custom = true;
6194 }
6195 }
6196 }
6197
6198 assert!(
6199 found_custom,
6200 "Custom port client should find service on custom port"
6201 );
6202 assert!(
6203 !found_default_on_custom,
6204 "Custom port client should NOT find service on default port"
6205 );
6206
6207 let client_default = ServiceDaemon::new().expect("Failed to create default port client");
6210 let browse_default = client_default
6211 .browse(service_type)
6212 .expect("Failed to browse on default port");
6213
6214 let mut found_default = false;
6215 let mut found_custom_on_default = false;
6216
6217 while let Ok(event) = browse_default.recv_timeout(timeout) {
6218 if let ServiceEvent::ServiceResolved(info) = event {
6219 println!(
6220 "Default port client resolved: {} on port {}",
6221 info.get_fullname(),
6222 info.get_port()
6223 );
6224 if info.get_fullname().starts_with(instance_default) {
6225 found_default = true;
6226 assert_eq!(info.get_port(), 8081);
6227 }
6228 if info.get_fullname().starts_with(instance_custom) {
6229 found_custom_on_default = true;
6230 }
6231 }
6232 }
6233
6234 assert!(
6235 found_default,
6236 "Default port client should find service on default port"
6237 );
6238 assert!(
6239 !found_custom_on_default,
6240 "Default port client should NOT find service on custom port"
6241 );
6242
6243 server_custom.shutdown().unwrap();
6245 client_custom.shutdown().unwrap();
6246 server_default.shutdown().unwrap();
6247 client_default.shutdown().unwrap();
6248 }
6249}