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, max_pkt_absolute, DnsAddress, DnsEntryExt, DnsIncoming, DnsOutgoing,
38 DnsPointer, DnsRecordBox, DnsRecordExt, DnsSrv, DnsTxt, InterfaceId, RRType, ScopedIp,
39 CLASS_CACHE_FLUSH, CLASS_IN, FLAGS_AA, FLAGS_QR_QUERY, FLAGS_QR_RESPONSE,
40 MAX_PKT_ABSOLUTE_IPV6, MAX_PKT_DEFAULT,
41 },
42 error::{e_fmt, Error, Result},
43 service_info::{
44 valid_ip_on_intf, DnsRegistry, MyIntf, Probe, ServiceInfo, ServiceStatus,
45 MULTICAST_RATE_LIMIT_MILLIS,
46 },
47 Receiver, ResolvedService, TxtProperties,
48};
49use flume::{bounded, Sender, TrySendError};
50use if_addrs::{IfAddr, Interface};
51use mio::{event::Source, net::UdpSocket as MioUdpSocket, Interest, Poll, Registry, Token};
52use socket2::Domain;
53use socket_pktinfo::PktInfoUdpSocket;
54use std::{
55 cmp::{self, Reverse},
56 collections::{hash_map::Entry, BinaryHeap, HashMap, HashSet},
57 fmt, io,
58 net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, UdpSocket},
59 str, thread,
60 time::Duration,
61 vec,
62};
63
64pub const SERVICE_NAME_LEN_MAX_DEFAULT: u8 = 15;
68
69pub const IP_CHECK_INTERVAL_IN_SECS_DEFAULT: u32 = 5;
71
72pub const VERIFY_TIMEOUT_DEFAULT: Duration = Duration::from_secs(10);
75
76pub(crate) const MIN_MAX_PACKET_SIZE: usize = 512;
78
79pub const MDNS_PORT: u16 = 5353;
81
82const GROUP_ADDR_V4: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 251);
83const GROUP_ADDR_V6: Ipv6Addr = Ipv6Addr::new(0xff02, 0, 0, 0, 0, 0, 0, 0xfb);
84const LOOPBACK_V4: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
85
86const RESOLVE_WAIT_IN_MILLIS: u64 = 500;
87
88const ANNOUNCE_SECOND_DELAY_MILLIS: u64 = MULTICAST_RATE_LIMIT_MILLIS + 100;
96
97const ANNOUNCE_SECOND_JITTER_MILLIS: u64 = 50;
100
101#[allow(clippy::assertions_on_constants)]
105const _: () = assert!(ANNOUNCE_SECOND_DELAY_MILLIS > MULTICAST_RATE_LIMIT_MILLIS);
106
107const SHARED_RESPONSE_DELAY_MIN_MILLIS: u64 = 10;
115
116const SHARED_RESPONSE_DELAY_MAX_MILLIS: u64 = 50;
118
119const INITIAL_QUERY_DELAY_MIN_MILLIS: u64 = 10;
127const INITIAL_QUERY_DELAY_MAX_MILLIS: u64 = 50;
128
129#[derive(Debug)]
131pub enum UnregisterStatus {
132 OK,
134 NotFound,
136}
137
138#[derive(Debug, PartialEq, Clone, Eq)]
140#[non_exhaustive]
141pub enum DaemonStatus {
142 Running,
144
145 Shutdown,
147}
148
149#[derive(Hash, Eq, PartialEq)]
152enum Counter {
153 Register,
154 RegisterResend,
155 Unregister,
156 UnregisterResend,
157 Browse,
158 ResolveHostname,
159 Respond,
160 CacheRefreshPTR,
161 CacheRefreshSrvTxt,
162 CacheRefreshAddr,
163 KnownAnswerSuppression,
164 CachedPTR,
165 CachedSRV,
166 CachedAddr,
167 CachedTxt,
168 CachedNSec,
169 CachedSubtype,
170 DnsRegistryProbe,
171 DnsRegistryActive,
172 DnsRegistryTimer,
173 DnsRegistryNameChange,
174 Timer,
175}
176
177impl fmt::Display for Counter {
178 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
179 match self {
180 Self::Register => write!(f, "register"),
181 Self::RegisterResend => write!(f, "register-resend"),
182 Self::Unregister => write!(f, "unregister"),
183 Self::UnregisterResend => write!(f, "unregister-resend"),
184 Self::Browse => write!(f, "browse"),
185 Self::ResolveHostname => write!(f, "resolve-hostname"),
186 Self::Respond => write!(f, "respond"),
187 Self::CacheRefreshPTR => write!(f, "cache-refresh-ptr"),
188 Self::CacheRefreshSrvTxt => write!(f, "cache-refresh-srv-txt"),
189 Self::CacheRefreshAddr => write!(f, "cache-refresh-addr"),
190 Self::KnownAnswerSuppression => write!(f, "known-answer-suppression"),
191 Self::CachedPTR => write!(f, "cached-ptr"),
192 Self::CachedSRV => write!(f, "cached-srv"),
193 Self::CachedAddr => write!(f, "cached-addr"),
194 Self::CachedTxt => write!(f, "cached-txt"),
195 Self::CachedNSec => write!(f, "cached-nsec"),
196 Self::CachedSubtype => write!(f, "cached-subtype"),
197 Self::DnsRegistryProbe => write!(f, "dns-registry-probe"),
198 Self::DnsRegistryActive => write!(f, "dns-registry-active"),
199 Self::DnsRegistryTimer => write!(f, "dns-registry-timer"),
200 Self::DnsRegistryNameChange => write!(f, "dns-registry-name-change"),
201 Self::Timer => write!(f, "timer"),
202 }
203 }
204}
205
206#[derive(Debug)]
207enum InternalError {
208 IntfAddrInvalid(Interface),
209}
210
211impl fmt::Display for InternalError {
212 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
213 match self {
214 InternalError::IntfAddrInvalid(iface) => write!(f, "interface addr invalid: {iface:?}"),
215 }
216 }
217}
218
219type MyResult<T> = core::result::Result<T, InternalError>;
220
221struct MyUdpSocket {
226 pktinfo: PktInfoUdpSocket,
229
230 mio: MioUdpSocket,
233}
234
235impl MyUdpSocket {
236 pub fn new(pktinfo: PktInfoUdpSocket) -> io::Result<Self> {
237 let std_sock = pktinfo.try_clone_std()?;
238 let mio = MioUdpSocket::from_std(std_sock);
239
240 Ok(Self { pktinfo, mio })
241 }
242}
243
244impl Source for MyUdpSocket {
246 fn register(
247 &mut self,
248 registry: &Registry,
249 token: Token,
250 interests: Interest,
251 ) -> io::Result<()> {
252 self.mio.register(registry, token, interests)
253 }
254
255 fn reregister(
256 &mut self,
257 registry: &Registry,
258 token: Token,
259 interests: Interest,
260 ) -> io::Result<()> {
261 self.mio.reregister(registry, token, interests)
262 }
263
264 fn deregister(&mut self, registry: &Registry) -> std::io::Result<()> {
265 self.mio.deregister(registry)
266 }
267}
268
269pub type Metrics = HashMap<String, i64>;
272
273const IPV4_SOCK_EVENT_KEY: usize = 4; const IPV6_SOCK_EVENT_KEY: usize = 6; const SIGNAL_SOCK_EVENT_KEY: usize = usize::MAX - 1; #[derive(Clone)]
281pub struct ServiceDaemon {
282 sender: Sender<Command>,
284
285 signal_addr: SocketAddr,
291}
292
293impl ServiceDaemon {
294 pub fn new() -> Result<Self> {
310 Self::new_with_port(MDNS_PORT)
311 }
312
313 pub fn new_with_port(port: u16) -> Result<Self> {
345 let signal_addr = SocketAddrV4::new(LOOPBACK_V4, 0);
348
349 let signal_sock = UdpSocket::bind(signal_addr)
350 .map_err(|e| e_fmt!("failed to create signal_sock for daemon: {}", e))?;
351
352 let signal_addr = signal_sock
354 .local_addr()
355 .map_err(|e| e_fmt!("failed to get signal sock addr: {}", e))?;
356
357 signal_sock
359 .set_nonblocking(true)
360 .map_err(|e| e_fmt!("failed to set nonblocking for signal socket: {}", e))?;
361
362 let poller = Poll::new().map_err(|e| e_fmt!("failed to create mio Poll: {e}"))?;
363
364 let (sender, receiver) = bounded(100);
365
366 let mio_sock = MioUdpSocket::from_std(signal_sock);
368 let cmd_sender = sender.clone();
369 thread::Builder::new()
370 .name("mDNS_daemon".to_string())
371 .spawn(move || {
372 Self::daemon_thread(mio_sock, poller, receiver, port, cmd_sender, signal_addr)
373 })
374 .map_err(|e| e_fmt!("thread builder failed to spawn: {}", e))?;
375
376 Ok(Self {
377 sender,
378 signal_addr,
379 })
380 }
381
382 fn send_cmd(&self, cmd: Command) -> Result<()> {
385 let cmd_name = cmd.to_string();
386
387 self.sender.try_send(cmd).map_err(|e| match e {
389 TrySendError::Full(_) => Error::Again,
390 TrySendError::Disconnected(_) => Error::DaemonShutdown,
391 })?;
392
393 let addr = SocketAddrV4::new(LOOPBACK_V4, 0);
395 let socket = UdpSocket::bind(addr)
396 .map_err(|e| e_fmt!("Failed to create socket to send signal: {}", e))?;
397 socket
398 .send_to(cmd_name.as_bytes(), self.signal_addr)
399 .map_err(|e| {
400 e_fmt!(
401 "signal socket send_to {} ({}) failed: {}",
402 self.signal_addr,
403 cmd_name,
404 e
405 )
406 })?;
407
408 Ok(())
409 }
410
411 pub fn browse(&self, service_type: &str) -> Result<Receiver<ServiceEvent>> {
431 check_domain_suffix(service_type)?;
432
433 let (resp_s, resp_r) = bounded(10);
434 self.send_cmd(Command::Browse(service_type.to_string(), 1, false, resp_s))?;
435 Ok(resp_r)
436 }
437
438 pub fn browse_cache(&self, service_type: &str) -> Result<Receiver<ServiceEvent>> {
451 check_domain_suffix(service_type)?;
452
453 let (resp_s, resp_r) = bounded(10);
454 self.send_cmd(Command::Browse(service_type.to_string(), 1, true, resp_s))?;
455 Ok(resp_r)
456 }
457
458 pub fn stop_browse(&self, ty_domain: &str) -> Result<()> {
466 self.send_cmd(Command::StopBrowse(ty_domain.to_string()))
467 }
468
469 pub fn resolve_hostname(
489 &self,
490 hostname: &str,
491 timeout: Option<u64>,
492 ) -> Result<Receiver<HostnameResolutionEvent>> {
493 check_hostname(hostname)?;
494 let (resp_s, resp_r) = bounded(10);
495 self.send_cmd(Command::ResolveHostname(
496 hostname.to_string(),
497 1,
498 resp_s,
499 timeout,
500 ))?;
501 Ok(resp_r)
502 }
503
504 pub fn stop_resolve_hostname(&self, hostname: &str) -> Result<()> {
510 self.send_cmd(Command::StopResolveHostname(hostname.to_string()))
511 }
512
513 pub fn register(&self, service_info: ServiceInfo) -> Result<()> {
533 check_service_name(service_info.get_fullname())?;
534 check_hostname(service_info.get_hostname())?;
535
536 self.send_cmd(Command::Register(service_info.into()))
537 }
538
539 pub fn unregister(&self, fullname: &str) -> Result<Receiver<UnregisterStatus>> {
550 let (resp_s, resp_r) = bounded(1);
551 self.send_cmd(Command::Unregister(fullname.to_lowercase(), resp_s))?;
552 Ok(resp_r)
553 }
554
555 pub fn monitor(&self) -> Result<Receiver<DaemonEvent>> {
565 let (resp_s, resp_r) = bounded(100);
566 self.send_cmd(Command::Monitor(resp_s))?;
567 Ok(resp_r)
568 }
569
570 pub fn shutdown(&self) -> Result<Receiver<DaemonStatus>> {
578 let (resp_s, resp_r) = bounded(1);
579 self.send_cmd(Command::Exit(resp_s))?;
580 Ok(resp_r)
581 }
582
583 pub fn status(&self) -> Result<Receiver<DaemonStatus>> {
591 let (resp_s, resp_r) = bounded(1);
592
593 if self.sender.is_disconnected() {
594 resp_s
595 .send(DaemonStatus::Shutdown)
596 .map_err(|e| e_fmt!("failed to send daemon status to the client: {}", e))?;
597 } else {
598 self.send_cmd(Command::GetStatus(resp_s))?;
599 }
600
601 Ok(resp_r)
602 }
603
604 pub fn get_metrics(&self) -> Result<Receiver<Metrics>> {
615 let (resp_s, resp_r) = bounded(1);
616 self.send_cmd(Command::GetMetrics(resp_s))?;
617 Ok(resp_r)
618 }
619
620 pub fn set_service_name_len_max(&self, len_max: u8) -> Result<()> {
635 const SERVICE_NAME_LEN_MAX_LIMIT: u8 = 30; if len_max > SERVICE_NAME_LEN_MAX_LIMIT {
638 return Err(Error::Msg(format!(
639 "service name length max {len_max} is too large"
640 )));
641 }
642
643 self.send_cmd(Command::SetOption(DaemonOption::ServiceNameLenMax(len_max)))
644 }
645
646 pub fn set_max_packet_size(&self, if_kind: impl IntoIfKindVec, size: usize) -> Result<()> {
661 if size < MIN_MAX_PACKET_SIZE {
662 return Err(Error::Msg(format!(
663 "max packet size {size} is too small, must be at least {MIN_MAX_PACKET_SIZE}"
664 )));
665 }
666
667 if size > MAX_PKT_ABSOLUTE_IPV6 {
668 return Err(Error::Msg(format!(
669 "max packet size {size} is too big, must be at most {MAX_PKT_ABSOLUTE_IPV6}"
670 )));
671 }
672
673 let if_kind_vec = if_kind.into_vec();
674 self.send_cmd(Command::SetOption(DaemonOption::MaxPacketSize(
675 if_kind_vec.kinds,
676 size,
677 )))
678 }
679
680 pub fn set_ip_check_interval(&self, interval_in_secs: u32) -> Result<()> {
686 let interval_in_millis = interval_in_secs as u64 * 1000;
687 self.send_cmd(Command::SetOption(DaemonOption::IpCheckInterval(
688 interval_in_millis,
689 )))
690 }
691
692 pub fn get_ip_check_interval(&self) -> Result<u32> {
694 let (resp_s, resp_r) = bounded(1);
695 self.send_cmd(Command::GetOption(resp_s))?;
696
697 let option = resp_r
698 .recv_timeout(Duration::from_secs(10))
699 .map_err(|e| e_fmt!("failed to receive ip check interval: {}", e))?;
700 let ip_check_interval_in_secs = option.ip_check_interval / 1000;
701 Ok(ip_check_interval_in_secs as u32)
702 }
703
704 pub fn enable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()> {
711 let if_kind_vec = if_kind.into_vec();
712 self.send_cmd(Command::SetOption(DaemonOption::EnableInterface(
713 if_kind_vec.kinds,
714 )))
715 }
716
717 pub fn disable_interface(&self, if_kind: impl IntoIfKindVec) -> Result<()> {
724 let if_kind_vec = if_kind.into_vec();
725 self.send_cmd(Command::SetOption(DaemonOption::DisableInterface(
726 if_kind_vec.kinds,
727 )))
728 }
729
730 pub fn accept_unsolicited(&self, accept: bool) -> Result<()> {
741 self.send_cmd(Command::SetOption(DaemonOption::AcceptUnsolicited(accept)))
742 }
743
744 pub fn include_apple_p2p(&self, include: bool) -> Result<()> {
747 self.send_cmd(Command::SetOption(DaemonOption::IncludeAppleP2P(include)))
748 }
749
750 #[cfg(test)]
751 pub fn test_down_interface(&self, ifname: &str) -> Result<()> {
752 self.send_cmd(Command::SetOption(DaemonOption::TestDownInterface(
753 ifname.to_string(),
754 )))
755 }
756
757 #[cfg(test)]
758 pub fn test_up_interface(&self, ifname: &str) -> Result<()> {
759 self.send_cmd(Command::SetOption(DaemonOption::TestUpInterface(
760 ifname.to_string(),
761 )))
762 }
763
764 pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()> {
780 self.send_cmd(Command::SetOption(DaemonOption::MulticastLoopV4(on)))
781 }
782
783 pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()> {
799 self.send_cmd(Command::SetOption(DaemonOption::MulticastLoopV6(on)))
800 }
801
802 pub fn verify(&self, instance_fullname: String, timeout: Duration) -> Result<()> {
821 self.send_cmd(Command::Verify(instance_fullname, timeout))
822 }
823
824 fn daemon_thread(
825 signal_sock: MioUdpSocket,
826 poller: Poll,
827 receiver: Receiver<Command>,
828 port: u16,
829 cmd_sender: Sender<Command>,
830 signal_addr: SocketAddr,
831 ) {
832 let mut zc = Zeroconf::new(signal_sock, poller, port, cmd_sender, signal_addr);
833
834 if let Some(cmd) = zc.run(receiver) {
835 match cmd {
836 Command::Exit(resp_s) => {
837 if let Err(e) = resp_s.send(DaemonStatus::Shutdown) {
840 debug!("exit: failed to send response of shutdown: {}", e);
841 }
842 }
843 _ => {
844 debug!("Unexpected command: {:?}", cmd);
845 }
846 }
847 }
848 }
849}
850
851fn _new_socket_bind(intf: &Interface, should_loop: bool) -> Result<MyUdpSocket> {
853 let intf_ip = &intf.ip();
856 match intf_ip {
857 IpAddr::V4(ip) => {
858 let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), MDNS_PORT);
859 let sock = new_socket(addr.into(), true)?;
860
861 sock.join_multicast_v4(&GROUP_ADDR_V4, ip)
863 .map_err(|e| e_fmt!("join multicast group on addr {}: {}", intf_ip, e))?;
864
865 sock.set_multicast_if_v4(ip)
867 .map_err(|e| e_fmt!("set multicast_if on addr {}: {}", ip, e))?;
868
869 sock.set_multicast_ttl_v4(255)
874 .map_err(|e| e_fmt!("set set_multicast_ttl_v4 on addr {}: {}", ip, e))?;
875
876 if !should_loop {
877 sock.set_multicast_loop_v4(false)
878 .map_err(|e| e_fmt!("failed to set multicast loop v4 for {ip}: {e}"))?;
879 }
880
881 let multicast_addr = SocketAddrV4::new(GROUP_ADDR_V4, MDNS_PORT).into();
883 let test_packets = DnsOutgoing::new(0).to_data_on_wire(MAX_PKT_DEFAULT, true);
884 for packet in test_packets {
885 sock.send_to(&packet, &multicast_addr)
886 .map_err(|e| e_fmt!("send multicast packet on addr {}: {}", ip, e))?;
887 }
888 MyUdpSocket::new(sock)
889 .map_err(|e| e_fmt!("failed to create MySocket for interface {}: {e}", intf.name))
890 }
891 IpAddr::V6(ip) => {
892 let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), MDNS_PORT, 0, 0);
893 let sock = new_socket(addr.into(), true)?;
894
895 let if_index = intf.index.unwrap_or(0);
896
897 sock.join_multicast_v6(&GROUP_ADDR_V6, if_index)
899 .map_err(|e| e_fmt!("join multicast group on addr {}: {}", ip, e))?;
900
901 sock.set_multicast_if_v6(if_index)
903 .map_err(|e| e_fmt!("set multicast_if on addr {}: {}", ip, e))?;
904
905 MyUdpSocket::new(sock)
910 .map_err(|e| e_fmt!("failed to create MySocket for interface {}: {e}", intf.name))
911 }
912 }
913}
914
915fn new_socket(addr: SocketAddr, non_block: bool) -> Result<PktInfoUdpSocket> {
918 let domain = match addr {
919 SocketAddr::V4(_) => socket2::Domain::IPV4,
920 SocketAddr::V6(_) => socket2::Domain::IPV6,
921 };
922
923 let fd = PktInfoUdpSocket::new(domain).map_err(|e| e_fmt!("create socket failed: {}", e))?;
924
925 fd.set_reuse_address(true)
926 .map_err(|e| e_fmt!("set ReuseAddr failed: {}", e))?;
927 #[cfg(unix)]
928 if let Err(e) = fd.set_reuse_port(true) {
929 debug!(
930 "SO_REUSEPORT is not supported, continuing without it: {}",
931 e
932 );
933 }
934
935 if non_block {
936 fd.set_nonblocking(true)
937 .map_err(|e| e_fmt!("set O_NONBLOCK: {}", e))?;
938 }
939
940 fd.bind(&addr.into())
941 .map_err(|e| e_fmt!("socket bind to {} failed: {}", &addr, e))?;
942
943 trace!("new socket bind to {}", &addr);
944 Ok(fd)
945}
946
947struct ReRun {
949 next_time: u64,
951 command: Command,
952}
953
954struct DelayedResponse {
956 next_time: u64,
958 out: DnsOutgoing,
959 if_index: u32,
960 is_ipv4: bool,
961}
962
963#[derive(Debug, Clone)]
967#[non_exhaustive]
968pub enum IfKind {
969 All,
971
972 IPv4,
974
975 IPv6,
977
978 Name(String),
980
981 Addr(IpAddr),
985
986 LoopbackV4,
990
991 LoopbackV6,
993
994 IndexV4(u32),
996
997 IndexV6(u32),
999
1000 Predicate(IfPredicate),
1002}
1003
1004impl IfKind {
1005 pub(crate) fn matches(&self, intf: &Interface) -> bool {
1007 match self {
1008 Self::All => true,
1009 Self::IPv4 => intf.ip().is_ipv4(),
1010 Self::IPv6 => intf.ip().is_ipv6(),
1011 Self::Name(ifname) => ifname == &intf.name,
1012 Self::Addr(addr) => addr == &intf.ip(),
1013 Self::LoopbackV4 => intf.is_loopback() && intf.ip().is_ipv4(),
1014 Self::LoopbackV6 => intf.is_loopback() && intf.ip().is_ipv6(),
1015 Self::IndexV4(idx) => intf.index == Some(*idx) && intf.ip().is_ipv4(),
1016 Self::IndexV6(idx) => intf.index == Some(*idx) && intf.ip().is_ipv6(),
1017 Self::Predicate(p) => p.matches(intf),
1018 }
1019 }
1020}
1021
1022impl From<&str> for IfKind {
1025 fn from(val: &str) -> Self {
1026 Self::Name(val.to_string())
1027 }
1028}
1029
1030impl From<&String> for IfKind {
1031 fn from(val: &String) -> Self {
1032 Self::Name(val.to_string())
1033 }
1034}
1035
1036impl From<IpAddr> for IfKind {
1038 fn from(val: IpAddr) -> Self {
1039 Self::Addr(val)
1040 }
1041}
1042
1043pub struct IfKindVec {
1045 kinds: Vec<IfKind>,
1046}
1047
1048pub trait IntoIfKindVec {
1050 fn into_vec(self) -> IfKindVec;
1051}
1052
1053impl<T: Into<IfKind>> IntoIfKindVec for T {
1054 fn into_vec(self) -> IfKindVec {
1055 let if_kind: IfKind = self.into();
1056 IfKindVec {
1057 kinds: vec![if_kind],
1058 }
1059 }
1060}
1061
1062impl<T: Into<IfKind>> IntoIfKindVec for Vec<T> {
1063 fn into_vec(self) -> IfKindVec {
1064 let kinds: Vec<IfKind> = self.into_iter().map(|x| x.into()).collect();
1065 IfKindVec { kinds }
1066 }
1067}
1068
1069#[derive(Clone)]
1071pub struct IfPredicate(std::sync::Arc<dyn Fn(&Interface) -> bool + Send + Sync>);
1072
1073impl IfPredicate {
1074 pub fn new(predicate: impl Fn(&Interface) -> bool + Send + Sync + 'static) -> Self {
1085 Self(std::sync::Arc::new(predicate))
1086 }
1087
1088 pub(crate) fn matches(&self, intf: &Interface) -> bool {
1089 self.0(intf)
1090 }
1091}
1092
1093impl std::fmt::Debug for IfPredicate {
1094 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1095 write!(f, "IfPredicate(...)")
1096 }
1097}
1098
1099struct IfSelection {
1101 if_kind: IfKind,
1103
1104 selected: bool,
1106}
1107
1108struct MaxPacketSizeSelection {
1110 if_kind: IfKind,
1112
1113 max_packet_size: usize,
1115}
1116
1117struct Zeroconf {
1119 port: u16,
1122
1123 my_intfs: HashMap<u32, MyIntf>,
1125
1126 ipv4_sock: Option<MyUdpSocket>,
1128
1129 ipv6_sock: Option<MyUdpSocket>,
1131
1132 my_services: HashMap<String, ServiceInfo>,
1134
1135 cache: DnsCache,
1137
1138 dns_registry_map: HashMap<u32, DnsRegistry>,
1140
1141 service_queriers: HashMap<String, Sender<ServiceEvent>>, hostname_resolvers: HashMap<String, (Sender<HostnameResolutionEvent>, Option<u64>)>, retransmissions: Vec<ReRun>,
1152
1153 delayed_responses: Vec<DelayedResponse>,
1155
1156 counters: Metrics,
1157
1158 poller: Poll,
1160
1161 monitors: Vec<Sender<DaemonEvent>>,
1163
1164 service_name_len_max: u8,
1166
1167 ip_check_interval: u64,
1169
1170 max_packet_sizes: Vec<MaxPacketSizeSelection>,
1173
1174 if_selections: Vec<IfSelection>,
1176
1177 signal_sock: MioUdpSocket,
1179
1180 timers: BinaryHeap<Reverse<u64>>,
1186
1187 status: DaemonStatus,
1188
1189 pending_resolves: HashSet<String>,
1191
1192 resolved: HashSet<String>,
1194
1195 multicast_loop_v4: bool,
1196
1197 multicast_loop_v6: bool,
1198
1199 accept_unsolicited: bool,
1200
1201 include_apple_p2p: bool,
1202
1203 cmd_sender: Sender<Command>,
1204
1205 signal_addr: SocketAddr,
1206
1207 #[cfg(test)]
1208 test_down_interfaces: HashSet<String>,
1209}
1210
1211fn join_multicast_group(my_sock: &PktInfoUdpSocket, intf: &Interface) -> Result<()> {
1213 let intf_ip = &intf.ip();
1214 match intf_ip {
1215 IpAddr::V4(ip) => {
1216 debug!("join multicast group V4 on {} addr {ip}", intf.name);
1218 my_sock
1219 .join_multicast_v4(&GROUP_ADDR_V4, ip)
1220 .map_err(|e| e_fmt!("PKT join multicast group on addr {}: {}", intf_ip, e))?;
1221 }
1222 IpAddr::V6(ip) => {
1223 let if_index = intf.index.unwrap_or(0);
1224 debug!(
1226 "join multicast group V6 on {} addr {ip} with index {if_index}",
1227 intf.name
1228 );
1229 my_sock
1230 .join_multicast_v6(&GROUP_ADDR_V6, if_index)
1231 .map_err(|e| e_fmt!("PKT join multicast group on addr {}: {}", ip, e))?;
1232 }
1233 }
1234 Ok(())
1235}
1236
1237impl Zeroconf {
1238 fn new(
1239 signal_sock: MioUdpSocket,
1240 poller: Poll,
1241 port: u16,
1242 cmd_sender: Sender<Command>,
1243 signal_addr: SocketAddr,
1244 ) -> Self {
1245 let my_ifaddrs = my_ip_interfaces(true);
1247
1248 let mut my_intfs = HashMap::new();
1252 let mut dns_registry_map = HashMap::new();
1253
1254 let mut ipv4_sock = None;
1257 let addr = SocketAddrV4::new(Ipv4Addr::new(0, 0, 0, 0), port);
1258 match new_socket(addr.into(), true) {
1259 Ok(sock) => {
1260 sock.set_multicast_ttl_v4(255)
1265 .map_err(|e| e_fmt!("set set_multicast_ttl_v4 on addr: {}", e))
1266 .ok();
1267
1268 ipv4_sock = match MyUdpSocket::new(sock) {
1270 Ok(s) => Some(s),
1271 Err(e) => {
1272 debug!("failed to create IPv4 MyUdpSocket: {e}");
1273 None
1274 }
1275 };
1276 }
1277 Err(e) => debug!("failed to create IPv4 socket: {e}"),
1279 }
1280
1281 let mut ipv6_sock = None;
1282 let addr = SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0), port, 0, 0);
1283 match new_socket(addr.into(), true) {
1284 Ok(sock) => {
1285 sock.set_multicast_hops_v6(255)
1289 .map_err(|e| e_fmt!("set set_multicast_hops_v6: {}", e))
1290 .ok();
1291
1292 ipv6_sock = match MyUdpSocket::new(sock) {
1294 Ok(s) => Some(s),
1295 Err(e) => {
1296 debug!("failed to create IPv6 MyUdpSocket: {e}");
1297 None
1298 }
1299 };
1300 }
1301 Err(e) => debug!("failed to create IPv6 socket: {e}"),
1302 }
1303
1304 for intf in my_ifaddrs {
1306 let sock_opt = if intf.ip().is_ipv4() {
1307 &ipv4_sock
1308 } else {
1309 &ipv6_sock
1310 };
1311 let Some(sock) = sock_opt else {
1312 debug!(
1313 "no socket available for interface {} with addr {}. Skipped.",
1314 intf.name,
1315 intf.ip()
1316 );
1317 continue;
1318 };
1319
1320 if let Err(e) = join_multicast_group(&sock.pktinfo, &intf) {
1321 debug!("failed to join multicast: {}: {e}. Skipped.", &intf.ip());
1322 }
1323
1324 let if_index = intf.index.unwrap_or(0);
1325
1326 dns_registry_map
1328 .entry(if_index)
1329 .or_insert_with(DnsRegistry::new);
1330
1331 my_intfs
1332 .entry(if_index)
1333 .and_modify(|v: &mut MyIntf| {
1334 v.addrs.insert(intf.addr.clone());
1335 })
1336 .or_insert(MyIntf {
1337 name: intf.name.clone(),
1338 index: if_index,
1339 addrs: HashSet::from([intf.addr]),
1340 max_packet_size_v4: MAX_PKT_DEFAULT,
1341 max_packet_size_v6: MAX_PKT_DEFAULT,
1342 });
1343 }
1344
1345 let monitors = Vec::new();
1346 let service_name_len_max = SERVICE_NAME_LEN_MAX_DEFAULT;
1347 let ip_check_interval = IP_CHECK_INTERVAL_IN_SECS_DEFAULT as u64 * 1000;
1348
1349 let timers = BinaryHeap::new();
1350
1351 let if_selections = vec![];
1353
1354 let status = DaemonStatus::Running;
1355
1356 Self {
1357 port,
1358 my_intfs,
1359 ipv4_sock,
1360 ipv6_sock,
1361 my_services: HashMap::new(),
1362 cache: DnsCache::new(),
1363 dns_registry_map,
1364 hostname_resolvers: HashMap::new(),
1365 service_queriers: HashMap::new(),
1366 retransmissions: Vec::new(),
1367 delayed_responses: Vec::new(),
1368 counters: HashMap::new(),
1369 poller,
1370 monitors,
1371 service_name_len_max,
1372 ip_check_interval,
1373 max_packet_sizes: Vec::new(),
1374 if_selections,
1375 signal_sock,
1376 timers,
1377 status,
1378 pending_resolves: HashSet::new(),
1379 resolved: HashSet::new(),
1380 multicast_loop_v4: true,
1381 multicast_loop_v6: true,
1382 accept_unsolicited: false,
1383 include_apple_p2p: false,
1384 cmd_sender,
1385 signal_addr,
1386
1387 #[cfg(test)]
1388 test_down_interfaces: HashSet::new(),
1389 }
1390 }
1391
1392 fn send_cmd_to_self(&self, cmd: Command) -> Result<()> {
1394 let cmd_name = cmd.to_string();
1395
1396 self.cmd_sender.try_send(cmd).map_err(|e| match e {
1397 TrySendError::Full(_) => Error::Again,
1398 TrySendError::Disconnected(_) => Error::DaemonShutdown,
1399 })?;
1400
1401 let addr = SocketAddrV4::new(LOOPBACK_V4, 0);
1402 let socket = UdpSocket::bind(addr)
1403 .map_err(|e| e_fmt!("Failed to create socket to send signal: {}", e))?;
1404 socket
1405 .send_to(cmd_name.as_bytes(), self.signal_addr)
1406 .map_err(|e| {
1407 e_fmt!(
1408 "signal socket send_to {} ({}) failed: {}",
1409 self.signal_addr,
1410 cmd_name,
1411 e
1412 )
1413 })?;
1414
1415 Ok(())
1416 }
1417
1418 fn cleanup(&mut self) {
1427 debug!("Starting cleanup for shutdown");
1428
1429 let service_names: Vec<String> = self.my_services.keys().cloned().collect();
1431 for fullname in service_names {
1432 if let Some(info) = self.my_services.get(&fullname) {
1433 debug!("Unregistering service during shutdown: {}", &fullname);
1434
1435 for intf in self.my_intfs.values() {
1436 if let Some(sock) = self.ipv4_sock.as_ref() {
1437 self.unregister_service(info, intf, &sock.pktinfo);
1438 }
1439
1440 if let Some(sock) = self.ipv6_sock.as_ref() {
1441 self.unregister_service(info, intf, &sock.pktinfo);
1442 }
1443 }
1444 }
1445 }
1446 self.my_services.clear();
1447
1448 let browse_types: Vec<String> = self.service_queriers.keys().cloned().collect();
1450 for ty_domain in browse_types {
1451 debug!("Stopping browse during shutdown: {}", &ty_domain);
1452 if let Some(sender) = self.service_queriers.remove(&ty_domain) {
1453 if let Err(e) = sender.send(ServiceEvent::SearchStopped(ty_domain.clone())) {
1455 debug!("Failed to send SearchStopped during shutdown: {}", e);
1456 }
1457 }
1458 }
1459
1460 let hostnames: Vec<String> = self.hostname_resolvers.keys().cloned().collect();
1462 for hostname in hostnames {
1463 debug!(
1464 "Stopping hostname resolution during shutdown: {}",
1465 &hostname
1466 );
1467 if let Some((sender, _timeout)) = self.hostname_resolvers.remove(&hostname) {
1468 if let Err(e) =
1470 sender.send(HostnameResolutionEvent::SearchStopped(hostname.clone()))
1471 {
1472 debug!(
1473 "Failed to send HostnameResolutionEvent::SearchStopped during shutdown: {}",
1474 e
1475 );
1476 }
1477 }
1478 }
1479
1480 self.retransmissions.clear();
1482
1483 self.delayed_responses.clear();
1485
1486 debug!("Cleanup completed");
1487 }
1488
1489 fn run(&mut self, receiver: Receiver<Command>) -> Option<Command> {
1498 if let Err(e) = self.poller.registry().register(
1500 &mut self.signal_sock,
1501 mio::Token(SIGNAL_SOCK_EVENT_KEY),
1502 mio::Interest::READABLE,
1503 ) {
1504 debug!("failed to add signal socket to the poller: {}", e);
1505 return None;
1506 }
1507
1508 if let Some(sock) = self.ipv4_sock.as_mut() {
1509 if let Err(e) = self.poller.registry().register(
1510 sock,
1511 mio::Token(IPV4_SOCK_EVENT_KEY),
1512 mio::Interest::READABLE,
1513 ) {
1514 debug!("failed to register ipv4 socket: {}", e);
1515 return None;
1516 }
1517 }
1518
1519 if let Some(sock) = self.ipv6_sock.as_mut() {
1520 if let Err(e) = self.poller.registry().register(
1521 sock,
1522 mio::Token(IPV6_SOCK_EVENT_KEY),
1523 mio::Interest::READABLE,
1524 ) {
1525 debug!("failed to register ipv6 socket: {}", e);
1526 return None;
1527 }
1528 }
1529
1530 let mut next_ip_check = if self.ip_check_interval > 0 {
1532 current_time_millis() + self.ip_check_interval
1533 } else {
1534 0
1535 };
1536
1537 if next_ip_check > 0 {
1538 self.add_timer(next_ip_check);
1539 }
1540
1541 let mut events = mio::Events::with_capacity(1024);
1544 loop {
1545 let now = current_time_millis();
1546
1547 let earliest_timer = self.peek_earliest_timer();
1548 let timeout = earliest_timer.map(|timer| {
1549 let millis = if timer > now { timer - now } else { 1 };
1551 Duration::from_millis(millis)
1552 });
1553
1554 events.clear();
1556 match self.poller.poll(&mut events, timeout) {
1557 Ok(_) => self.handle_poller_events(&events),
1558 Err(e) => debug!("failed to select from sockets: {}", e),
1559 }
1560
1561 let now = current_time_millis();
1562
1563 self.pop_timers_till(now);
1565
1566 for hostname in self
1568 .hostname_resolvers
1569 .clone()
1570 .into_iter()
1571 .filter(|(_, (_, timeout))| timeout.map(|t| now >= t).unwrap_or(false))
1572 .map(|(hostname, _)| hostname)
1573 {
1574 trace!("hostname resolver timeout for {}", &hostname);
1575 call_hostname_resolution_listener(
1576 &self.hostname_resolvers,
1577 &hostname,
1578 HostnameResolutionEvent::SearchTimeout(hostname.to_owned()),
1579 );
1580 call_hostname_resolution_listener(
1581 &self.hostname_resolvers,
1582 &hostname,
1583 HostnameResolutionEvent::SearchStopped(hostname.to_owned()),
1584 );
1585 self.hostname_resolvers.remove(&hostname);
1586 }
1587
1588 while let Ok(command) = receiver.try_recv() {
1590 if matches!(command, Command::Exit(_)) {
1591 debug!("Exit command received, performing cleanup");
1592 self.cleanup();
1593 self.status = DaemonStatus::Shutdown;
1594 return Some(command);
1595 }
1596 self.exec_command(command, false);
1597 }
1598
1599 let mut i = 0;
1601 while i < self.retransmissions.len() {
1602 if now >= self.retransmissions[i].next_time {
1603 let rerun = self.retransmissions.remove(i);
1604 self.exec_command(rerun.command, true);
1605 } else {
1606 i += 1;
1607 }
1608 }
1609
1610 let mut i = 0;
1612 while i < self.delayed_responses.len() {
1613 if now >= self.delayed_responses[i].next_time {
1614 let resp = self.delayed_responses.remove(i);
1615 self.send_delayed_response(resp);
1616 } else {
1617 i += 1;
1618 }
1619 }
1620
1621 self.refresh_active_services();
1623
1624 let mut query_count = 0;
1626 for (hostname, _sender) in self.hostname_resolvers.iter() {
1627 for (hostname, ip_addr) in
1628 self.cache.refresh_due_hostname_resolutions(hostname).iter()
1629 {
1630 self.send_query(hostname, ip_address_rr_type(&ip_addr.to_ip_addr()));
1631 query_count += 1;
1632 }
1633 }
1634
1635 self.increase_counter(Counter::CacheRefreshAddr, query_count);
1636
1637 let now = current_time_millis();
1639
1640 let expired_services = self.cache.evict_expired_services(now);
1642 if !expired_services.is_empty() {
1643 debug!(
1644 "run: send {} service removal to listeners",
1645 expired_services.len()
1646 );
1647 self.notify_service_removal(expired_services);
1648 }
1649
1650 let expired_addrs = self.cache.evict_expired_addr(now);
1652 for (hostname, addrs) in expired_addrs {
1653 call_hostname_resolution_listener(
1654 &self.hostname_resolvers,
1655 &hostname,
1656 HostnameResolutionEvent::AddressesRemoved(hostname.clone(), addrs),
1657 );
1658 let instances = self.cache.get_instances_on_host(&hostname);
1659 let instance_set: HashSet<String> = instances.into_iter().collect();
1660 self.resolve_updated_instances(&instance_set);
1661 }
1662
1663 self.probing_handler();
1665
1666 if now >= next_ip_check && next_ip_check > 0 {
1668 next_ip_check = now + self.ip_check_interval;
1669 self.add_timer(next_ip_check);
1670
1671 self.check_ip_changes();
1672 }
1673 }
1674 }
1675
1676 fn process_set_option(&mut self, daemon_opt: DaemonOption) {
1677 match daemon_opt {
1678 DaemonOption::ServiceNameLenMax(length) => self.service_name_len_max = length,
1679 DaemonOption::IpCheckInterval(interval) => self.ip_check_interval = interval,
1680 DaemonOption::MaxPacketSize(if_kind, size) => self.set_max_packet_size(if_kind, size),
1681 DaemonOption::EnableInterface(if_kind) => self.enable_interface(if_kind),
1682 DaemonOption::DisableInterface(if_kind) => self.disable_interface(if_kind),
1683 DaemonOption::MulticastLoopV4(on) => self.set_multicast_loop_v4(on),
1684 DaemonOption::MulticastLoopV6(on) => self.set_multicast_loop_v6(on),
1685 DaemonOption::AcceptUnsolicited(accept) => self.set_accept_unsolicited(accept),
1686 DaemonOption::IncludeAppleP2P(enable) => self.set_apple_p2p(enable),
1687 #[cfg(test)]
1688 DaemonOption::TestDownInterface(ifname) => {
1689 self.test_down_interfaces.insert(ifname);
1690 }
1691 #[cfg(test)]
1692 DaemonOption::TestUpInterface(ifname) => {
1693 self.test_down_interfaces.remove(&ifname);
1694 }
1695 }
1696 }
1697
1698 fn enable_interface(&mut self, kinds: Vec<IfKind>) {
1699 debug!("enable_interface: {:?}", kinds);
1700 let interfaces = my_ip_interfaces_inner(true, self.include_apple_p2p);
1701
1702 for if_kind in kinds {
1703 self.if_selections.push(IfSelection {
1704 if_kind: resolve_addr_to_index(if_kind, &interfaces),
1705 selected: true,
1706 });
1707 }
1708
1709 self.apply_intf_selections(interfaces);
1710 }
1711
1712 fn disable_interface(&mut self, kinds: Vec<IfKind>) {
1713 debug!("disable_interface: {:?}", kinds);
1714 let interfaces = my_ip_interfaces_inner(true, self.include_apple_p2p);
1715
1716 for if_kind in kinds {
1717 self.if_selections.push(IfSelection {
1718 if_kind: resolve_addr_to_index(if_kind, &interfaces),
1719 selected: false,
1720 });
1721 }
1722
1723 self.apply_intf_selections(interfaces);
1724 }
1725
1726 fn set_max_packet_size(&mut self, kinds: Vec<IfKind>, size: usize) {
1727 debug!("set_max_packet_size: {:?} {}", kinds, size);
1728 let interfaces = my_ip_interfaces_inner(true, self.include_apple_p2p);
1729
1730 for if_kind in kinds {
1731 self.max_packet_sizes.push(MaxPacketSizeSelection {
1732 if_kind: resolve_addr_to_index(if_kind, &interfaces),
1733 max_packet_size: size,
1734 });
1735 }
1736
1737 self.apply_max_packet_sizes(&interfaces);
1738 }
1739
1740 fn apply_max_packet_sizes(&mut self, interfaces: &[Interface]) {
1743 for (if_index, my_intf) in self.my_intfs.iter_mut() {
1744 let v4 = resolve_max_packet_size(&self.max_packet_sizes, interfaces, *if_index, true);
1745 let v6 = resolve_max_packet_size(&self.max_packet_sizes, interfaces, *if_index, false);
1746
1747 if my_intf.max_packet_size_v4 != v4 || my_intf.max_packet_size_v6 != v6 {
1748 debug!(
1749 "interface {}: max packet size v4 {} -> {v4}, v6 {} -> {v6}",
1750 my_intf.name, my_intf.max_packet_size_v4, my_intf.max_packet_size_v6
1751 );
1752 my_intf.max_packet_size_v4 = v4;
1753 my_intf.max_packet_size_v6 = v6;
1754 }
1755 }
1756 }
1757
1758 fn set_multicast_loop_v4(&mut self, on: bool) {
1759 let Some(sock) = self.ipv4_sock.as_mut() else {
1760 return;
1761 };
1762 self.multicast_loop_v4 = on;
1763 sock.pktinfo
1764 .set_multicast_loop_v4(on)
1765 .map_err(|e| e_fmt!("failed to set multicast loop v4: {}", e))
1766 .unwrap();
1767 }
1768
1769 fn set_multicast_loop_v6(&mut self, on: bool) {
1770 let Some(sock) = self.ipv6_sock.as_mut() else {
1771 return;
1772 };
1773 self.multicast_loop_v6 = on;
1774 sock.pktinfo
1775 .set_multicast_loop_v6(on)
1776 .map_err(|e| e_fmt!("failed to set multicast loop v6: {}", e))
1777 .unwrap();
1778 }
1779
1780 fn set_accept_unsolicited(&mut self, accept: bool) {
1781 self.accept_unsolicited = accept;
1782 }
1783
1784 fn set_apple_p2p(&mut self, include: bool) {
1785 if self.include_apple_p2p != include {
1786 self.include_apple_p2p = include;
1787 self.apply_intf_selections(my_ip_interfaces_inner(true, self.include_apple_p2p));
1788 }
1789 }
1790
1791 fn notify_monitors(&mut self, event: DaemonEvent) {
1792 self.monitors.retain(|sender| {
1794 if let Err(e) = sender.try_send(event.clone()) {
1795 debug!("notify_monitors: try_send: {}", &e);
1796 if matches!(e, TrySendError::Disconnected(_)) {
1797 return false; }
1799 }
1800 true
1801 });
1802 }
1803
1804 fn del_addr_in_my_services(&mut self, addr: &IpAddr) {
1806 for (_, service_info) in self.my_services.iter_mut() {
1807 if service_info.is_addr_auto() {
1808 service_info.remove_ipaddr(addr);
1809 }
1810 }
1811 }
1812
1813 fn add_timer(&mut self, next_time: u64) {
1814 self.timers.push(Reverse(next_time));
1815 }
1816
1817 fn peek_earliest_timer(&self) -> Option<u64> {
1818 self.timers.peek().map(|Reverse(v)| *v)
1819 }
1820
1821 fn _pop_earliest_timer(&mut self) -> Option<u64> {
1822 self.timers.pop().map(|Reverse(v)| v)
1823 }
1824
1825 fn pop_timers_till(&mut self, now: u64) {
1827 while let Some(Reverse(v)) = self.timers.peek() {
1828 if *v > now {
1829 break;
1830 }
1831 self.timers.pop();
1832 }
1833 }
1834
1835 fn selected_intfs(&self, interfaces: Vec<Interface>) -> HashSet<Interface> {
1837 let intf_count = interfaces.len();
1838 let mut intf_selections = vec![true; intf_count];
1839
1840 for selection in self.if_selections.iter() {
1842 for i in 0..intf_count {
1844 if selection.if_kind.matches(&interfaces[i]) {
1845 intf_selections[i] = selection.selected;
1846 }
1847 }
1848 }
1849
1850 let mut selected_addrs = HashSet::new();
1851 for i in 0..intf_count {
1852 if intf_selections[i] {
1853 selected_addrs.insert(interfaces[i].clone());
1854 }
1855 }
1856
1857 selected_addrs
1858 }
1859
1860 fn apply_intf_selections(&mut self, interfaces: Vec<Interface>) {
1865 let intf_count = interfaces.len();
1867 let mut intf_selections = vec![true; intf_count];
1868
1869 for selection in self.if_selections.iter() {
1871 for i in 0..intf_count {
1873 if selection.if_kind.matches(&interfaces[i]) {
1874 intf_selections[i] = selection.selected;
1875 }
1876 }
1877 }
1878
1879 for (idx, intf) in interfaces.iter().enumerate() {
1881 if intf_selections[idx] {
1882 self.add_interface(intf, &interfaces);
1884 } else {
1885 self.del_interface_addr(intf);
1887 }
1888 }
1889
1890 self.apply_max_packet_sizes(&interfaces);
1893 }
1894
1895 fn del_ip(&mut self, ip: IpAddr) {
1896 self.del_addr_in_my_services(&ip);
1897 self.notify_monitors(DaemonEvent::IpDel(ip));
1898 }
1899
1900 fn check_ip_changes(&mut self) {
1902 let my_ifaddrs = my_ip_interfaces_inner(true, self.include_apple_p2p);
1904
1905 #[cfg(test)]
1906 let my_ifaddrs: Vec<_> = my_ifaddrs
1907 .into_iter()
1908 .filter(|intf| !self.test_down_interfaces.contains(&intf.name))
1909 .collect();
1910
1911 let ifaddrs_map: HashMap<u32, Vec<&IfAddr>> =
1912 my_ifaddrs.iter().fold(HashMap::new(), |mut acc, intf| {
1913 let if_index = intf.index.unwrap_or(0);
1914 acc.entry(if_index).or_default().push(&intf.addr);
1915 acc
1916 });
1917
1918 let mut deleted_intfs = Vec::new();
1919 let mut deleted_ips = Vec::new();
1920
1921 for (if_index, my_intf) in self.my_intfs.iter_mut() {
1922 let mut last_ipv4 = None;
1923 let mut last_ipv6 = None;
1924
1925 if let Some(current_addrs) = ifaddrs_map.get(if_index) {
1926 my_intf.addrs.retain(|addr| {
1927 if current_addrs.contains(&addr) {
1928 true
1929 } else {
1930 match addr.ip() {
1931 IpAddr::V4(ipv4) => last_ipv4 = Some(ipv4),
1932 IpAddr::V6(ipv6) => last_ipv6 = Some(ipv6),
1933 }
1934 deleted_ips.push(addr.ip());
1935 false
1936 }
1937 });
1938 if my_intf.addrs.is_empty() {
1939 deleted_intfs.push((*if_index, last_ipv4, last_ipv6))
1940 }
1941 } else {
1942 debug!(
1944 "check_ip_changes: interface {} ({}) no longer exists, removing",
1945 my_intf.name, if_index
1946 );
1947 for addr in my_intf.addrs.iter() {
1948 match addr.ip() {
1949 IpAddr::V4(ipv4) => last_ipv4 = Some(ipv4),
1950 IpAddr::V6(ipv6) => last_ipv6 = Some(ipv6),
1951 }
1952 deleted_ips.push(addr.ip())
1953 }
1954 deleted_intfs.push((*if_index, last_ipv4, last_ipv6));
1955 }
1956 }
1957
1958 if !deleted_ips.is_empty() || !deleted_intfs.is_empty() {
1959 debug!(
1960 "check_ip_changes: {} deleted ips {} deleted intfs",
1961 deleted_ips.len(),
1962 deleted_intfs.len()
1963 );
1964 }
1965
1966 for ip in deleted_ips {
1967 self.del_ip(ip);
1968 }
1969
1970 for (if_index, last_ipv4, last_ipv6) in deleted_intfs {
1971 let Some(my_intf) = self.my_intfs.remove(&if_index) else {
1972 continue;
1973 };
1974
1975 if let Some(ipv4) = last_ipv4 {
1976 debug!("leave multicast for {ipv4}");
1977 if let Some(sock) = self.ipv4_sock.as_mut() {
1978 if let Err(e) = sock.pktinfo.leave_multicast_v4(&GROUP_ADDR_V4, &ipv4) {
1979 debug!("leave multicast group for addr {ipv4}: {e}");
1980 }
1981 }
1982 }
1983
1984 if let Some(ipv6) = last_ipv6 {
1985 debug!("leave multicast for {ipv6}");
1986 if let Some(sock) = self.ipv6_sock.as_mut() {
1987 if let Err(e) = sock
1988 .pktinfo
1989 .leave_multicast_v6(&GROUP_ADDR_V6, my_intf.index)
1990 {
1991 debug!("leave multicast group for IPv6: {ipv6}: {e}");
1992 }
1993 }
1994 }
1995
1996 let intf_id = InterfaceId {
1998 name: my_intf.name.to_string(),
1999 index: my_intf.index,
2000 };
2001 let result = self.cache.remove_records_on_intf(intf_id);
2002 self.notify_service_removal(result.removed_instances);
2003 self.resolve_updated_instances(&result.modified_instances);
2004 }
2005
2006 self.apply_intf_selections(my_ifaddrs);
2008 }
2009
2010 fn del_interface_addr(&mut self, intf: &Interface) {
2013 let if_index = intf.index.unwrap_or(0);
2014 debug!(
2015 "del_interface_addr: {} ({if_index}) addr {}",
2016 intf.name,
2017 intf.ip()
2018 );
2019
2020 let Some(my_intf) = self.my_intfs.get_mut(&if_index) else {
2021 debug!("del_interface_addr: interface {} not found", intf.name);
2022 return;
2023 };
2024
2025 let mut ip_removed = false;
2026
2027 if my_intf.addrs.remove(&intf.addr) {
2028 ip_removed = true;
2029
2030 match intf.addr.ip() {
2031 IpAddr::V4(ipv4) => {
2032 if my_intf.next_ifaddr_v4().is_none() {
2033 if let Some(sock) = self.ipv4_sock.as_mut() {
2034 if let Err(e) = sock.pktinfo.leave_multicast_v4(&GROUP_ADDR_V4, &ipv4) {
2035 debug!("leave multicast group for addr {ipv4}: {e}");
2036 } else {
2037 debug!("leave multicast for {ipv4}");
2038 }
2039 }
2040 }
2041 }
2042
2043 IpAddr::V6(ipv6) => {
2044 if my_intf.next_ifaddr_v6().is_none() {
2045 if let Some(sock) = self.ipv6_sock.as_mut() {
2046 if let Err(e) =
2047 sock.pktinfo.leave_multicast_v6(&GROUP_ADDR_V6, if_index)
2048 {
2049 debug!("leave multicast group for addr {ipv6}: {e}");
2050 }
2051 }
2052 }
2053 }
2054 }
2055
2056 if my_intf.addrs.is_empty() {
2057 debug!("del_interface_addr: removing interface {}", intf.name);
2059 self.my_intfs.remove(&if_index);
2060 self.dns_registry_map.remove(&if_index);
2061 self.cache
2062 .remove_addrs_on_disabled_intf(if_index, IpType::BOTH);
2063 } else {
2064 let is_v4 = intf.addr.ip().is_ipv4();
2068 let version_gone = if is_v4 {
2069 my_intf.next_ifaddr_v4().is_none()
2070 } else {
2071 my_intf.next_ifaddr_v6().is_none()
2072 };
2073 if version_gone {
2074 let ip_type = if is_v4 { IpType::V4 } else { IpType::V6 };
2075 self.cache.remove_addrs_on_disabled_intf(if_index, ip_type);
2076 }
2077 }
2078 }
2079
2080 if ip_removed {
2081 self.notify_monitors(DaemonEvent::IpDel(intf.ip()));
2083 self.del_addr_in_my_services(&intf.ip());
2085 }
2086 }
2087
2088 fn add_interface(&mut self, intf: &Interface, interfaces: &[Interface]) {
2093 let sock_opt = if intf.ip().is_ipv4() {
2094 &self.ipv4_sock
2095 } else {
2096 &self.ipv6_sock
2097 };
2098
2099 let Some(sock) = sock_opt else {
2100 debug!(
2101 "add_interface: no socket available for interface {} with addr {}. Skipped.",
2102 intf.name,
2103 intf.ip()
2104 );
2105 return;
2106 };
2107
2108 let if_index = intf.index.unwrap_or(0);
2109 let mut new_addr = false;
2110
2111 match self.my_intfs.entry(if_index) {
2112 Entry::Occupied(mut entry) => {
2113 let my_intf = entry.get_mut();
2115 if !my_intf.addrs.contains(&intf.addr) {
2116 if let Err(e) = join_multicast_group(&sock.pktinfo, intf) {
2117 debug!("add_interface: socket_config {}: {e}", &intf.name);
2118 }
2119 my_intf.addrs.insert(intf.addr.clone());
2120 new_addr = true;
2121 }
2122 }
2123 Entry::Vacant(entry) => {
2124 if let Err(e) = join_multicast_group(&sock.pktinfo, intf) {
2125 debug!("add_interface: socket_config {}: {e}. Skipped.", &intf.name);
2126 return;
2127 }
2128
2129 new_addr = true;
2130 let new_intf = MyIntf {
2131 name: intf.name.clone(),
2132 index: if_index,
2133 addrs: HashSet::from([intf.addr.clone()]),
2134 max_packet_size_v4: MAX_PKT_DEFAULT,
2135 max_packet_size_v6: MAX_PKT_DEFAULT,
2136 };
2137 entry.insert(new_intf);
2138 }
2139 }
2140
2141 if !new_addr {
2142 trace!("add_interface: interface {} already exists", &intf.name);
2143 return;
2144 }
2145
2146 debug!("add new interface {}: {}", intf.name, intf.ip());
2147
2148 let v4 = resolve_max_packet_size(&self.max_packet_sizes, interfaces, if_index, true);
2150 let v6 = resolve_max_packet_size(&self.max_packet_sizes, interfaces, if_index, false);
2151 if let Some(my_intf) = self.my_intfs.get_mut(&if_index) {
2152 my_intf.max_packet_size_v4 = v4;
2153 my_intf.max_packet_size_v6 = v6;
2154 }
2155
2156 let Some(my_intf) = self.my_intfs.get(&if_index) else {
2157 debug!("add_interface: cannot find if_index {if_index}");
2158 return;
2159 };
2160
2161 let dns_registry = match self.dns_registry_map.get_mut(&if_index) {
2162 Some(registry) => registry,
2163 None => self
2164 .dns_registry_map
2165 .entry(if_index)
2166 .or_insert_with(DnsRegistry::new),
2167 };
2168
2169 for (_, service_info) in self.my_services.iter_mut() {
2170 if service_info.is_addr_auto() {
2171 service_info.insert_ipaddr(intf);
2172
2173 if let Ok(true) = announce_service_on_intf(
2174 dns_registry,
2175 service_info,
2176 my_intf,
2177 &sock.pktinfo,
2178 self.port,
2179 ) {
2180 debug!(
2181 "Announce service {} on {}",
2182 service_info.get_fullname(),
2183 intf.ip()
2184 );
2185 service_info.set_status(if_index, ServiceStatus::Announced);
2186 } else {
2187 for timer in dns_registry.new_timers.drain(..) {
2188 self.timers.push(Reverse(timer));
2189 }
2190 service_info.set_status(if_index, ServiceStatus::Probing);
2191 }
2192 }
2193 }
2194
2195 if let Some(my_intf) = self.my_intfs.get(&if_index) {
2200 for ty in self.service_queriers.keys() {
2201 self.send_query_on_intf(ty, RRType::PTR, my_intf);
2202 }
2203 }
2204
2205 self.notify_monitors(DaemonEvent::IpAdd(intf.ip()));
2207 }
2208
2209 fn register_service(&mut self, mut info: ServiceInfo) {
2218 if let Err(e) = check_service_name_length(info.get_type(), self.service_name_len_max) {
2220 error!("check_service_name_length: {}", &e);
2221 self.notify_monitors(DaemonEvent::Error(e));
2222 return;
2223 }
2224
2225 if info.is_addr_auto() {
2226 let selected_intfs =
2227 self.selected_intfs(my_ip_interfaces_inner(true, self.include_apple_p2p));
2228 for intf in selected_intfs {
2229 info.insert_ipaddr(&intf);
2230 }
2231 }
2232
2233 debug!("register service {:?}", &info);
2234
2235 let outgoing_addrs = self.send_unsolicited_response(&mut info);
2236 if !outgoing_addrs.is_empty() {
2237 self.notify_monitors(DaemonEvent::Announce(
2238 info.get_fullname().to_string(),
2239 format!("{:?}", &outgoing_addrs),
2240 ));
2241 }
2242
2243 let service_fullname = info.get_fullname().to_lowercase();
2246 self.my_services.insert(service_fullname, info);
2247 }
2248
2249 fn send_unsolicited_response(&mut self, info: &mut ServiceInfo) -> Vec<IpAddr> {
2252 let mut outgoing_addrs = Vec::new();
2253 let mut outgoing_intfs = HashSet::new();
2254
2255 let mut invalid_intf_addrs = HashSet::new();
2256
2257 for (if_index, intf) in self.my_intfs.iter() {
2258 let dns_registry = match self.dns_registry_map.get_mut(if_index) {
2259 Some(registry) => registry,
2260 None => self
2261 .dns_registry_map
2262 .entry(*if_index)
2263 .or_insert_with(DnsRegistry::new),
2264 };
2265
2266 let mut announced = false;
2267
2268 if let Some(sock) = self.ipv4_sock.as_mut() {
2270 match announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port) {
2271 Ok(true) => {
2272 for addr in intf.addrs.iter().filter(|a| a.ip().is_ipv4()) {
2273 outgoing_addrs.push(addr.ip());
2274 }
2275 outgoing_intfs.insert(intf.index);
2276
2277 debug!(
2278 "Announce service IPv4 {} on {}",
2279 info.get_fullname(),
2280 intf.name
2281 );
2282 announced = true;
2283 }
2284 Ok(false) => {}
2285 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2286 invalid_intf_addrs.insert(intf_addr);
2287 }
2288 }
2289 }
2290
2291 if let Some(sock) = self.ipv6_sock.as_mut() {
2292 match announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port) {
2293 Ok(true) => {
2294 for addr in intf.addrs.iter().filter(|a| a.ip().is_ipv6()) {
2295 outgoing_addrs.push(addr.ip());
2296 }
2297 outgoing_intfs.insert(intf.index);
2298
2299 debug!(
2300 "Announce service IPv6 {} on {}",
2301 info.get_fullname(),
2302 intf.name
2303 );
2304 announced = true;
2305 }
2306 Ok(false) => {}
2307 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2308 invalid_intf_addrs.insert(intf_addr);
2309 }
2310 }
2311 }
2312
2313 if announced {
2314 info.set_status(intf.index, ServiceStatus::Announced);
2315 } else {
2316 for timer in dns_registry.new_timers.drain(..) {
2317 self.timers.push(Reverse(timer));
2318 }
2319 info.set_status(*if_index, ServiceStatus::Probing);
2320 }
2321 }
2322
2323 if !invalid_intf_addrs.is_empty() {
2324 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2325 }
2326
2327 let next_time = current_time_millis()
2331 + ANNOUNCE_SECOND_DELAY_MILLIS
2332 + fastrand::u64(0..ANNOUNCE_SECOND_JITTER_MILLIS);
2333 for if_index in outgoing_intfs {
2334 self.add_retransmission(
2335 next_time,
2336 Command::RegisterResend(info.get_fullname().to_string(), if_index),
2337 );
2338 }
2339
2340 outgoing_addrs
2341 }
2342
2343 fn probing_handler(&mut self) {
2345 let now = current_time_millis();
2346 let mut invalid_intf_addrs = HashSet::new();
2347
2348 for (if_index, intf) in self.my_intfs.iter() {
2349 let Some(dns_registry) = self.dns_registry_map.get_mut(if_index) else {
2350 continue;
2351 };
2352
2353 let (out, expired_probes) = check_probing(dns_registry, &mut self.timers, now);
2354
2355 if !out.questions().is_empty() {
2357 trace!("sending out probing of questions: {:?}", out.questions());
2358 if let Some(sock) = self.ipv4_sock.as_mut() {
2359 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2360 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2361 {
2362 invalid_intf_addrs.insert(intf_addr);
2363 }
2364 }
2365 if let Some(sock) = self.ipv6_sock.as_mut() {
2366 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2367 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2368 {
2369 invalid_intf_addrs.insert(intf_addr);
2370 }
2371 }
2372 }
2373
2374 let waiting_services =
2376 handle_expired_probes(expired_probes, &intf.name, dns_registry, &mut self.monitors);
2377
2378 for service_name in waiting_services {
2379 if let Some(info) = self.my_services.get_mut(&service_name.to_lowercase()) {
2381 if info.get_status(*if_index) == ServiceStatus::Announced {
2382 debug!("service {} already announced", info.get_fullname());
2383 continue;
2384 }
2385
2386 let announced_v4 = if let Some(sock) = self.ipv4_sock.as_mut() {
2387 match announce_service_on_intf(
2388 dns_registry,
2389 info,
2390 intf,
2391 &sock.pktinfo,
2392 self.port,
2393 ) {
2394 Ok(announced) => announced,
2395 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2396 invalid_intf_addrs.insert(intf_addr);
2397 false
2398 }
2399 }
2400 } else {
2401 false
2402 };
2403 let announced_v6 = if let Some(sock) = self.ipv6_sock.as_mut() {
2404 match announce_service_on_intf(
2405 dns_registry,
2406 info,
2407 intf,
2408 &sock.pktinfo,
2409 self.port,
2410 ) {
2411 Ok(announced) => announced,
2412 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2413 invalid_intf_addrs.insert(intf_addr);
2414 false
2415 }
2416 }
2417 } else {
2418 false
2419 };
2420
2421 if announced_v4 || announced_v6 {
2422 let next_time = now
2423 + ANNOUNCE_SECOND_DELAY_MILLIS
2424 + fastrand::u64(0..ANNOUNCE_SECOND_JITTER_MILLIS);
2425 let command =
2426 Command::RegisterResend(info.get_fullname().to_string(), *if_index);
2427 self.retransmissions.push(ReRun { next_time, command });
2428 self.timers.push(Reverse(next_time));
2429
2430 let fullname = dns_registry.resolve_name(&service_name).to_string();
2431
2432 let hostname = dns_registry.resolve_name(info.get_hostname());
2433
2434 debug!("wake up: announce service {} on {}", fullname, intf.name);
2435 notify_monitors(
2436 &mut self.monitors,
2437 DaemonEvent::Announce(fullname, format!("{}:{}", hostname, &intf.name)),
2438 );
2439
2440 info.set_status(*if_index, ServiceStatus::Announced);
2441 }
2442 }
2443 }
2444 }
2445
2446 if !invalid_intf_addrs.is_empty() {
2447 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2448 }
2449 }
2450
2451 fn unregister_service(
2452 &self,
2453 info: &ServiceInfo,
2454 intf: &MyIntf,
2455 sock: &PktInfoUdpSocket,
2456 ) -> Vec<u8> {
2457 let is_ipv4 = sock.domain() == Domain::IPV4;
2458
2459 let (fullname, hostname) = match self.dns_registry_map.get(&intf.index) {
2463 Some(dns_registry) => (
2464 dns_registry.resolve_name(info.get_fullname()),
2465 dns_registry.resolve_name(info.get_hostname()),
2466 ),
2467 None => (info.get_fullname(), info.get_hostname()),
2468 };
2469
2470 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
2471 out.add_answer_at_time(
2472 DnsPointer::new(
2473 info.get_type(),
2474 RRType::PTR,
2475 CLASS_IN,
2476 0,
2477 fullname.to_string(),
2478 ),
2479 0,
2480 );
2481
2482 if let Some(sub) = info.get_subtype() {
2483 trace!("Adding subdomain {}", sub);
2484 out.add_answer_at_time(
2485 DnsPointer::new(sub, RRType::PTR, CLASS_IN, 0, fullname.to_string()),
2486 0,
2487 );
2488 }
2489
2490 out.add_answer_at_time(
2491 DnsSrv::new(
2492 fullname,
2493 CLASS_IN | CLASS_CACHE_FLUSH,
2494 0,
2495 info.get_priority(),
2496 info.get_weight(),
2497 info.get_port(),
2498 hostname.to_string(),
2499 ),
2500 0,
2501 );
2502 out.add_answer_at_time(
2503 DnsTxt::new(
2504 fullname,
2505 CLASS_IN | CLASS_CACHE_FLUSH,
2506 0,
2507 info.generate_txt(),
2508 ),
2509 0,
2510 );
2511
2512 let if_addrs = if is_ipv4 {
2513 info.get_addrs_on_my_intf_v4(intf)
2514 } else {
2515 info.get_addrs_on_my_intf_v6(intf)
2516 };
2517
2518 if if_addrs.is_empty() {
2519 return vec![];
2520 }
2521
2522 for address in if_addrs {
2523 out.add_answer_at_time(
2524 DnsAddress::new(
2525 hostname,
2526 ip_address_rr_type(&address),
2527 CLASS_IN | CLASS_CACHE_FLUSH,
2528 0,
2529 address,
2530 intf.into(),
2531 ),
2532 0,
2533 );
2534 }
2535
2536 let sent_vec = match send_dns_outgoing(&out, intf, sock, self.port, None, None) {
2538 Ok(sent_vec) => sent_vec,
2539 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2540 let invalid_intf_addrs = HashSet::from([intf_addr]);
2541 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2542 vec![]
2543 }
2544 };
2545 sent_vec.into_iter().next().unwrap_or_default()
2546 }
2547
2548 fn add_hostname_resolver(
2552 &mut self,
2553 hostname: String,
2554 listener: Sender<HostnameResolutionEvent>,
2555 timeout: Option<u64>,
2556 ) {
2557 let real_timeout = timeout.map(|t| current_time_millis() + t);
2558 self.hostname_resolvers
2559 .insert(hostname.to_lowercase(), (listener, real_timeout));
2560 if let Some(t) = real_timeout {
2561 self.add_timer(t);
2562 }
2563 }
2564
2565 fn send_query(&self, name: &str, qtype: RRType) {
2567 self.send_query_vec(&[(name, qtype)]);
2568 }
2569
2570 fn send_query_on_intf(&self, name: &str, qtype: RRType, intf: &MyIntf) {
2575 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2576 out.add_question(name, qtype);
2577
2578 let mut invalid_intf_addrs = HashSet::new();
2579 if let Some(sock) = self.ipv4_sock.as_ref() {
2580 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2581 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2582 {
2583 invalid_intf_addrs.insert(intf_addr);
2584 }
2585 }
2586 if let Some(sock) = self.ipv6_sock.as_ref() {
2587 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2588 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2589 {
2590 invalid_intf_addrs.insert(intf_addr);
2591 }
2592 }
2593 if !invalid_intf_addrs.is_empty() {
2594 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2595 }
2596 }
2597
2598 fn send_query_vec(&self, questions: &[(&str, RRType)]) {
2600 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2601 let now = current_time_millis();
2602
2603 for (name, qtype) in questions {
2604 out.add_question(name, *qtype);
2605
2606 for record in self.cache.get_known_answers(name, *qtype, now) {
2607 trace!("add known answer: {:?}", record.record);
2615 let mut new_record = record.record.clone();
2616 new_record.get_record_mut().update_ttl(now);
2617 out.add_answer_box(new_record);
2618 }
2619 }
2620
2621 let mut invalid_intf_addrs = HashSet::new();
2622 for (_, intf) in self.my_intfs.iter() {
2623 if let Some(sock) = self.ipv4_sock.as_ref() {
2624 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2625 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2626 {
2627 invalid_intf_addrs.insert(intf_addr);
2628 }
2629 }
2630 if let Some(sock) = self.ipv6_sock.as_ref() {
2631 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2632 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2633 {
2634 invalid_intf_addrs.insert(intf_addr);
2635 }
2636 }
2637 }
2638
2639 if !invalid_intf_addrs.is_empty() {
2640 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2641 }
2642 }
2643
2644 fn handle_read(&mut self, event_key: usize) -> bool {
2649 let is_ipv4 = event_key == IPV4_SOCK_EVENT_KEY;
2650 let sock_opt = match event_key {
2651 IPV4_SOCK_EVENT_KEY => &mut self.ipv4_sock,
2652 IPV6_SOCK_EVENT_KEY => &mut self.ipv6_sock,
2653 _ => {
2654 debug!("handle_read: unknown token {}", event_key);
2655 return false;
2656 }
2657 };
2658 let Some(sock) = sock_opt.as_mut() else {
2659 debug!("handle_read: socket not available for token {}", event_key);
2660 return false;
2661 };
2662 let max_size = max_pkt_absolute(is_ipv4);
2666 let mut buf = vec![0u8; max_size + 1];
2667
2668 let (sz, pktinfo) = match sock.pktinfo.recv(&mut buf) {
2670 Ok(sz) => sz,
2671 Err(e) => {
2672 if e.kind() != std::io::ErrorKind::WouldBlock {
2673 debug!("listening socket read failed: {}", e);
2674 }
2675 return false;
2676 }
2677 };
2678
2679 if sz > max_size {
2688 debug!(
2689 "handle_read: dropping over-sized datagram of at least {} bytes (max {})",
2690 sz, max_size
2691 );
2692 return true; }
2694
2695 let pkt_if_index = pktinfo.if_index as u32;
2697 let Some(my_intf) = self.my_intfs.get(&pkt_if_index) else {
2698 debug!(
2699 "handle_read: no interface found for pktinfo if_index: {}",
2700 pktinfo.if_index
2701 );
2702 return true; };
2704
2705 let is_ipv4 = event_key == IPV4_SOCK_EVENT_KEY;
2710 if (is_ipv4 && my_intf.next_ifaddr_v4().is_none())
2711 || (!is_ipv4 && my_intf.next_ifaddr_v6().is_none())
2712 {
2713 debug!(
2714 "handle_read: dropping {} packet on intf {} (disabled)",
2715 if is_ipv4 { "IPv4" } else { "IPv6" },
2716 my_intf.name
2717 );
2718 return true;
2719 }
2720
2721 buf.truncate(sz); match DnsIncoming::new(buf, my_intf.into()) {
2724 Ok(msg) => {
2725 if msg.is_query() {
2726 let querier_addr = pktinfo.addr_src;
2727 self.handle_query(msg, pkt_if_index, querier_addr);
2728 } else if msg.is_response() {
2729 self.handle_response(msg, pkt_if_index);
2730 } else {
2731 debug!("Invalid message: not query and not response");
2732 }
2733 }
2734 Err(e) => debug!("Invalid incoming DNS message: {}", e),
2735 }
2736
2737 true
2738 }
2739
2740 fn query_unresolved(&mut self, instance: &str) -> bool {
2742 if !valid_instance_name(instance) {
2743 trace!("instance name {} not valid", instance);
2744 return false;
2745 }
2746
2747 if let Some(records) = self.cache.get_srv(instance) {
2748 for record in records {
2749 if let Some(srv) = record.record.any().downcast_ref::<DnsSrv>() {
2750 if self.cache.get_addr(srv.host()).is_none() {
2751 self.send_query_vec(&[(srv.host(), RRType::A), (srv.host(), RRType::AAAA)]);
2752 return true;
2753 }
2754 }
2755 }
2756 } else {
2757 self.send_query(instance, RRType::ANY);
2758 return true;
2759 }
2760
2761 false
2762 }
2763
2764 fn query_cache_for_service(
2767 &mut self,
2768 ty_domain: &str,
2769 sender: &Sender<ServiceEvent>,
2770 now: u64,
2771 ) {
2772 let mut resolved: HashSet<String> = HashSet::new();
2773 let mut unresolved: HashSet<String> = HashSet::new();
2774
2775 if let Some(records) = self.cache.get_ptr(ty_domain) {
2776 for record in records.iter().filter(|r| !r.record.expires_soon(now)) {
2777 if let Some(ptr) = record.record.any().downcast_ref::<DnsPointer>() {
2778 let mut new_event = None;
2779 match self.resolve_service_from_cache(ty_domain, ptr.alias()) {
2780 Ok(resolved_service) => {
2781 if resolved_service.is_valid() {
2782 debug!("Resolved service from cache: {}", ptr.alias());
2783 new_event =
2784 Some(ServiceEvent::ServiceResolved(Box::new(resolved_service)));
2785 } else {
2786 debug!("Resolved service is not valid: {}", ptr.alias());
2787 }
2788 }
2789 Err(err) => {
2790 debug!("Error while resolving service from cache: {}", err);
2791 continue;
2792 }
2793 }
2794
2795 match sender.send(ServiceEvent::ServiceFound(
2796 ty_domain.to_string(),
2797 ptr.alias().to_string(),
2798 )) {
2799 Ok(()) => debug!("sent service found {}", ptr.alias()),
2800 Err(e) => {
2801 debug!("failed to send service found: {}", e);
2802 continue;
2803 }
2804 }
2805
2806 if let Some(event) = new_event {
2807 resolved.insert(ptr.alias().to_string());
2808 match sender.send(event) {
2809 Ok(()) => debug!("sent service resolved: {}", ptr.alias()),
2810 Err(e) => debug!("failed to send service resolved: {}", e),
2811 }
2812 } else {
2813 unresolved.insert(ptr.alias().to_string());
2814 }
2815 }
2816 }
2817 }
2818
2819 for instance in resolved.drain() {
2820 self.pending_resolves.remove(&instance);
2821 self.resolved.insert(instance);
2822 }
2823
2824 for instance in unresolved.drain() {
2825 self.add_pending_resolve(instance);
2826 }
2827 }
2828
2829 fn query_cache_for_hostname(
2832 &mut self,
2833 hostname: &str,
2834 sender: Sender<HostnameResolutionEvent>,
2835 ) {
2836 let addresses_map = self.cache.get_addresses_for_host(hostname);
2837 for (name, addresses) in addresses_map {
2838 match sender.send(HostnameResolutionEvent::AddressesFound(name, addresses)) {
2839 Ok(()) => trace!("sent hostname addresses found"),
2840 Err(e) => debug!("failed to send hostname addresses found: {}", e),
2841 }
2842 }
2843 }
2844
2845 fn add_pending_resolve(&mut self, instance: String) {
2846 if !self.pending_resolves.contains(&instance) {
2847 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
2848 self.add_retransmission(next_time, Command::Resolve(instance.clone(), 1));
2849 self.pending_resolves.insert(instance);
2850 }
2851 }
2852
2853 fn resolve_service_from_cache(
2855 &self,
2856 ty_domain: &str,
2857 fullname: &str,
2858 ) -> Result<ResolvedService> {
2859 let now = current_time_millis();
2860 let mut resolved_service = ResolvedService {
2861 ty_domain: ty_domain.to_string(),
2862 sub_ty_domain: None,
2863 fullname: fullname.to_string(),
2864 host: String::new(),
2865 port: 0,
2866 addresses: HashSet::new(),
2867 txt_properties: TxtProperties::new(),
2868 };
2869
2870 if let Some(subtype) = self.cache.get_subtype(fullname) {
2872 trace!(
2873 "ty_domain: {} found subtype {} for instance: {}",
2874 ty_domain,
2875 subtype,
2876 fullname
2877 );
2878 if resolved_service.sub_ty_domain.is_none() {
2879 resolved_service.sub_ty_domain = Some(subtype.to_string());
2880 }
2881 }
2882
2883 if let Some(records) = self.cache.get_srv(fullname) {
2885 if let Some(answer) = records.iter().find(|r| !r.record.expires_soon(now)) {
2886 if let Some(dns_srv) = answer.record.any().downcast_ref::<DnsSrv>() {
2887 resolved_service.host = dns_srv.host().to_string();
2888 resolved_service.port = dns_srv.port();
2889 }
2890 }
2891 }
2892
2893 if let Some(records) = self.cache.get_txt(fullname) {
2895 if let Some(record) = records.iter().find(|r| !r.record.expires_soon(now)) {
2896 if let Some(dns_txt) = record.record.any().downcast_ref::<DnsTxt>() {
2897 resolved_service.txt_properties = dns_txt.text().into();
2898 }
2899 }
2900 }
2901
2902 if let Some(records) = self.cache.get_addr(&resolved_service.host) {
2904 for answer in records.iter() {
2905 if let Some(dns_a) = answer.record.any().downcast_ref::<DnsAddress>() {
2906 if dns_a.expires_soon(now) {
2907 trace!(
2908 "Addr expired or expires soon: {}",
2909 dns_a.address().to_ip_addr()
2910 );
2911 } else {
2912 let scoped = dns_a.address();
2913 if let ScopedIp::V4(v4) = &scoped {
2914 let existing = resolved_service
2917 .addresses
2918 .iter()
2919 .find(|a| a.to_ip_addr() == IpAddr::V4(*v4.addr()))
2920 .cloned();
2921 if let Some(mut existing) = existing {
2922 resolved_service.addresses.remove(&existing);
2923 if let ScopedIp::V4(existing_v4) = &mut existing {
2924 for id in v4.interface_ids() {
2925 existing_v4.add_interface_id(id.clone());
2926 }
2927 }
2928 resolved_service.addresses.insert(existing);
2929 } else {
2930 resolved_service.addresses.insert(scoped);
2931 }
2932 } else {
2933 resolved_service.addresses.insert(scoped);
2934 }
2935 }
2936 }
2937 }
2938 }
2939
2940 Ok(resolved_service)
2941 }
2942
2943 fn handle_poller_events(&mut self, events: &mio::Events) {
2944 for ev in events.iter() {
2945 trace!("event received with key {:?}", ev.token());
2946 if ev.token().0 == SIGNAL_SOCK_EVENT_KEY {
2947 self.signal_sock_drain();
2949
2950 if let Err(e) = self.poller.registry().reregister(
2951 &mut self.signal_sock,
2952 ev.token(),
2953 mio::Interest::READABLE,
2954 ) {
2955 debug!("failed to modify poller for signal socket: {}", e);
2956 }
2957 continue; }
2959
2960 while self.handle_read(ev.token().0) {}
2962
2963 if ev.token().0 == IPV4_SOCK_EVENT_KEY {
2965 if let Some(sock) = self.ipv4_sock.as_mut() {
2967 if let Err(e) =
2968 self.poller
2969 .registry()
2970 .reregister(sock, ev.token(), mio::Interest::READABLE)
2971 {
2972 debug!("modify poller for IPv4 socket: {}", e);
2973 }
2974 }
2975 } else if ev.token().0 == IPV6_SOCK_EVENT_KEY {
2976 if let Some(sock) = self.ipv6_sock.as_mut() {
2978 if let Err(e) =
2979 self.poller
2980 .registry()
2981 .reregister(sock, ev.token(), mio::Interest::READABLE)
2982 {
2983 debug!("modify poller for IPv6 socket: {}", e);
2984 }
2985 }
2986 }
2987 }
2988 }
2989
2990 fn handle_response(&mut self, mut msg: DnsIncoming, if_index: u32) {
2993 let now = current_time_millis();
2994
2995 let mut record_predicate = |record: &DnsRecordBox| {
2997 if !record.get_record().is_expired(now) {
2998 return true;
2999 }
3000
3001 debug!("record is expired, removing it from cache.");
3002 if self.cache.remove(record) {
3003 if let Some(dns_ptr) = record.any().downcast_ref::<DnsPointer>() {
3005 call_service_listener(
3006 &self.service_queriers,
3007 dns_ptr.get_name(),
3008 ServiceEvent::ServiceRemoved(
3009 dns_ptr.get_name().to_string(),
3010 dns_ptr.alias().to_string(),
3011 ),
3012 );
3013 }
3014 }
3015 false
3016 };
3017 msg.answers_mut().retain(&mut record_predicate);
3018 msg.authorities_mut().retain(&mut record_predicate);
3019 msg.additionals_mut().retain(&mut record_predicate);
3020
3021 self.conflict_handler(&msg, if_index);
3023
3024 let mut is_for_us = true; for answer in msg.answers() {
3031 if answer.get_type() == RRType::PTR {
3032 if self.service_queriers.contains_key(answer.get_name()) {
3033 is_for_us = true;
3034 break; } else {
3036 is_for_us = false;
3037 }
3038 } else if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
3039 let answer_lowercase = answer.get_name().to_lowercase();
3041 if self.hostname_resolvers.contains_key(&answer_lowercase) {
3042 is_for_us = true;
3043 break; }
3045 }
3046 }
3047
3048 if self.accept_unsolicited {
3050 is_for_us = true;
3051 }
3052
3053 struct InstanceChange {
3055 ty: RRType, name: String, }
3058
3059 let mut changes = Vec::new();
3067 let mut timers = Vec::new();
3068 let Some(my_intf) = self.my_intfs.get(&if_index) else {
3069 return;
3070 };
3071 for record in msg.all_records() {
3072 match self
3073 .cache
3074 .add_or_update(my_intf, record, &mut timers, is_for_us)
3075 {
3076 Some((dns_record, true)) => {
3077 timers.push(dns_record.record.get_record().get_expire_time());
3078 timers.push(dns_record.record.get_record().get_refresh_time());
3079
3080 let ty = dns_record.record.get_type();
3081 let name = dns_record.record.get_name();
3082
3083 debug!("cache: new record: {:?}", &dns_record.record);
3086
3087 if ty == RRType::PTR && dns_record.record.get_record().get_ttl() > 1 {
3089 if self.service_queriers.contains_key(name) {
3090 timers.push(dns_record.record.get_record().get_refresh_time());
3091 }
3092
3093 if let Some(dns_ptr) = dns_record.record.any().downcast_ref::<DnsPointer>()
3095 {
3096 debug!("calling listener with service found: {name}");
3097 call_service_listener(
3098 &self.service_queriers,
3099 name,
3100 ServiceEvent::ServiceFound(
3101 name.to_string(),
3102 dns_ptr.alias().to_string(),
3103 ),
3104 );
3105 changes.push(InstanceChange {
3106 ty,
3107 name: dns_ptr.alias().to_string(),
3108 });
3109 }
3110 } else {
3111 changes.push(InstanceChange {
3112 ty,
3113 name: name.to_string(),
3114 });
3115 }
3116 }
3117 Some((dns_record, false)) => {
3118 timers.push(dns_record.record.get_record().get_expire_time());
3119 timers.push(dns_record.record.get_record().get_refresh_time());
3120 }
3121 _ => {}
3122 }
3123 }
3124
3125 for t in timers {
3127 self.add_timer(t);
3128 }
3129
3130 for change in changes
3132 .iter()
3133 .filter(|change| change.ty == RRType::A || change.ty == RRType::AAAA)
3134 {
3135 let addr_map = self.cache.get_addresses_for_host(&change.name);
3136 for (name, addresses) in addr_map {
3137 call_hostname_resolution_listener(
3138 &self.hostname_resolvers,
3139 &change.name,
3140 HostnameResolutionEvent::AddressesFound(name, addresses),
3141 )
3142 }
3143 }
3144
3145 let mut updated_instances = HashSet::new();
3147 for update in changes {
3148 match update.ty {
3149 RRType::PTR | RRType::SRV | RRType::TXT => {
3150 updated_instances.insert(update.name);
3151 }
3152 RRType::A | RRType::AAAA => {
3153 let instances = self.cache.get_instances_on_host(&update.name);
3154 updated_instances.extend(instances);
3155 }
3156 _ => {}
3157 }
3158 }
3159
3160 self.resolve_updated_instances(&updated_instances);
3161 }
3162
3163 fn conflict_handler(&mut self, msg: &DnsIncoming, if_index: u32) {
3164 let Some(my_intf) = self.my_intfs.get(&if_index) else {
3165 debug!("handle_response: no intf found for index {if_index}");
3166 return;
3167 };
3168
3169 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3170 return;
3171 };
3172
3173 for answer in msg.answers().iter() {
3174 let mut new_records = Vec::new();
3175
3176 let name = answer.get_name();
3177 let Some(probe) = dns_registry.probing.get_mut(name) else {
3178 continue;
3179 };
3180
3181 if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
3183 if let Some(answer_addr) = answer.any().downcast_ref::<DnsAddress>() {
3184 if answer_addr.interface_id.index != if_index {
3185 debug!(
3186 "conflict handler: answer addr {:?} not in the subnet of intf {}",
3187 answer_addr, my_intf.name
3188 );
3189 continue;
3190 }
3191 }
3192
3193 let any_match = probe.records.iter().any(|r| {
3196 r.get_type() == answer.get_type()
3197 && r.get_class() == answer.get_class()
3198 && r.rrdata_match(answer.as_ref())
3199 });
3200 if any_match {
3201 continue; }
3203 }
3204
3205 probe.records.retain(|record| {
3206 if record.get_type() == answer.get_type()
3207 && record.get_class() == answer.get_class()
3208 && !record.rrdata_match(answer.as_ref())
3209 {
3210 debug!(
3211 "found conflict name: '{name}' record: {}: {} PEER: {}",
3212 record.get_type(),
3213 record.rdata_print(),
3214 answer.rdata_print()
3215 );
3216
3217 let mut new_record = record.clone();
3220 let new_name = match record.get_type() {
3221 RRType::A => hostname_change(name),
3222 RRType::AAAA => hostname_change(name),
3223 _ => name_change(name),
3224 };
3225 new_record.get_record_mut().set_new_name(new_name);
3226 new_records.push(new_record);
3227 return false; }
3229
3230 true
3231 });
3232
3233 let create_time = current_time_millis() + fastrand::u64(0..250);
3240
3241 let waiting_services = probe.waiting_services.clone();
3242
3243 for record in new_records {
3244 if dns_registry.update_hostname(name, record.get_name(), create_time) {
3245 self.timers.push(Reverse(create_time));
3246 }
3247
3248 dns_registry.name_changes.insert(
3250 record.get_record().get_original_name().to_string(),
3251 record.get_name().to_string(),
3252 );
3253
3254 let new_probe = match dns_registry.probing.get_mut(record.get_name()) {
3255 Some(p) => p,
3256 None => {
3257 let new_probe = dns_registry
3258 .probing
3259 .entry(record.get_name().to_string())
3260 .or_insert_with(|| {
3261 debug!("conflict handler: new probe of {}", record.get_name());
3262 Probe::new(create_time)
3263 });
3264 self.timers.push(Reverse(new_probe.next_send));
3265 new_probe
3266 }
3267 };
3268
3269 debug!(
3270 "insert record with new name '{}' {} into probe",
3271 record.get_name(),
3272 record.get_type()
3273 );
3274 new_probe.insert_record(record);
3275
3276 new_probe.waiting_services.extend(waiting_services.clone());
3277 }
3278 }
3279 }
3280
3281 fn resolve_updated_instances(&mut self, updated_instances: &HashSet<String>) {
3288 if updated_instances.is_empty() {
3289 return;
3290 }
3291
3292 let mut resolved: HashSet<String> = HashSet::new();
3293 let mut unresolved: HashSet<String> = HashSet::new();
3294 let mut removed_instances = HashMap::new();
3295
3296 let now = current_time_millis();
3297
3298 for (ty_domain, records) in self.cache.all_ptr().iter() {
3299 if !self.service_queriers.contains_key(ty_domain) {
3300 continue;
3302 }
3303
3304 for ptr in records.iter().filter(|r| !r.record.expires_soon(now)) {
3305 let Some(dns_ptr) = ptr.record.any().downcast_ref::<DnsPointer>() else {
3306 continue;
3307 };
3308
3309 let instance = dns_ptr.alias();
3310 if !updated_instances.contains(instance) {
3311 continue;
3312 }
3313
3314 let Ok(resolved_service) = self.resolve_service_from_cache(ty_domain, instance)
3315 else {
3316 continue;
3317 };
3318
3319 debug!("resolve_updated_instances: from cache: {instance}");
3320 if resolved_service.is_valid() {
3321 debug!(
3322 "resolved '{}' -> host '{}' port {} addrs {:?}",
3323 instance,
3324 resolved_service.host,
3325 resolved_service.port,
3326 resolved_service.addresses,
3327 );
3328 resolved.insert(instance.to_string());
3329 let event = ServiceEvent::ServiceResolved(Box::new(resolved_service));
3330 call_service_listener(&self.service_queriers, ty_domain, event);
3331 } else {
3332 debug!("Resolved service is not valid: {instance}");
3333 if self.resolved.remove(dns_ptr.alias()) {
3334 removed_instances
3335 .entry(ty_domain.to_string())
3336 .or_insert_with(HashSet::new)
3337 .insert(instance.to_string());
3338 }
3339 unresolved.insert(instance.to_string());
3340 }
3341 }
3342 }
3343
3344 for instance in resolved.drain() {
3345 self.pending_resolves.remove(&instance);
3346 self.resolved.insert(instance);
3347 }
3348
3349 for instance in unresolved.drain() {
3350 self.add_pending_resolve(instance);
3351 }
3352
3353 if !removed_instances.is_empty() {
3354 debug!(
3355 "resolve_updated_instances: removed {}",
3356 &removed_instances.len()
3357 );
3358 self.notify_service_removal(removed_instances);
3359 }
3360 }
3361
3362 fn handle_query(&mut self, msg: DnsIncoming, if_index: u32, querier_addr: SocketAddr) {
3364 let querier_ip = querier_addr.ip();
3365 let is_ipv4 = querier_ip.is_ipv4();
3366 let sock_opt = if is_ipv4 {
3367 &self.ipv4_sock
3368 } else {
3369 &self.ipv6_sock
3370 };
3371 let Some(sock) = sock_opt.as_ref() else {
3372 debug!("handle_query: socket not available for intf {}", if_index);
3373 return;
3374 };
3375
3376 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
3377 let mut delayed = false;
3378
3379 const META_QUERY: &str = "_services._dns-sd._udp.local.";
3382
3383 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3384 debug!("missing dns registry for intf {}", if_index);
3385 return;
3386 };
3387
3388 let Some(intf) = self.my_intfs.get(&if_index) else {
3389 debug!("handle_query: no intf found for index {if_index}");
3390 return;
3391 };
3392
3393 for question in msg.questions().iter() {
3394 let qtype = question.entry_type();
3395 let q_name = question.entry_name();
3396
3397 if qtype == RRType::PTR {
3398 if querier_addr.port() == MDNS_PORT && msg.num_authorities() == 0 {
3402 delayed = true;
3403 }
3404 for service in self.my_services.values() {
3405 if service.get_status(if_index) != ServiceStatus::Announced {
3406 continue;
3407 }
3408
3409 if service.matches_type_or_subtype(q_name) {
3410 out.add_answer_with_additionals(&msg, service, intf, dns_registry, is_ipv4);
3411 } else if q_name == META_QUERY {
3412 let ttl = service.get_other_ttl();
3413 let alias = service.get_type().to_string();
3414 let ptr = DnsPointer::new(q_name, RRType::PTR, CLASS_IN, ttl, alias);
3415 if !out.add_answer(&msg, ptr) {
3416 trace!("answer was not added for meta-query {:?}", &question);
3417 }
3418 }
3419 }
3420 } else {
3421 if qtype == RRType::ANY && msg.num_authorities() > 0 {
3423 if let Some(probe) = dns_registry.probing.get_mut(q_name) {
3424 probe.tiebreaking(&msg, q_name);
3425 }
3426 }
3427
3428 if qtype == RRType::A || qtype == RRType::AAAA || qtype == RRType::ANY {
3429 for service in self.my_services.values() {
3430 if service.get_status(if_index) != ServiceStatus::Announced {
3431 continue;
3432 }
3433
3434 let service_hostname = dns_registry.resolve_name(service.get_hostname());
3435
3436 if service_hostname.to_lowercase() == question.entry_name().to_lowercase() {
3437 let mut intf_addrs: Vec<IpAddr> = Vec::new();
3444 if qtype == RRType::A || qtype == RRType::ANY {
3445 intf_addrs.extend(service.get_addrs_on_my_intf_v4(intf));
3446 }
3447 if qtype == RRType::AAAA || qtype == RRType::ANY {
3448 intf_addrs.extend(service.get_addrs_on_my_intf_v6(intf));
3449 }
3450 if intf_addrs.is_empty()
3451 && (qtype == RRType::A || qtype == RRType::AAAA)
3452 {
3453 let t = match qtype {
3454 RRType::A => "TYPE_A",
3455 RRType::AAAA => "TYPE_AAAA",
3456 _ => "invalid_type",
3457 };
3458 trace!(
3459 "Cannot find valid addrs for {} response on intf {:?}",
3460 t,
3461 &intf
3462 );
3463 continue;
3464 }
3465 for address in intf_addrs {
3466 out.add_answer(
3467 &msg,
3468 DnsAddress::new(
3469 service_hostname,
3470 ip_address_rr_type(&address),
3471 CLASS_IN | CLASS_CACHE_FLUSH,
3472 service.get_host_ttl(),
3473 address,
3474 intf.into(),
3475 ),
3476 );
3477 }
3478 }
3479 }
3480 }
3481
3482 let query_name = q_name.to_lowercase();
3483 let service_opt = self
3484 .my_services
3485 .iter()
3486 .find(|(k, _v)| dns_registry.resolve_name(k.as_str()) == query_name)
3487 .map(|(_, v)| v);
3488
3489 let Some(service) = service_opt else {
3490 continue;
3491 };
3492
3493 if service.get_status(if_index) != ServiceStatus::Announced {
3494 continue;
3495 }
3496
3497 let intf_addrs = if is_ipv4 {
3498 service.get_addrs_on_my_intf_v4(intf)
3499 } else {
3500 service.get_addrs_on_my_intf_v6(intf)
3501 };
3502 if intf_addrs.is_empty() {
3503 debug!(
3504 "Cannot find valid addrs for TYPE_SRV response on intf {:?}",
3505 &intf
3506 );
3507 continue;
3508 }
3509
3510 add_answer_of_service(
3511 &mut out,
3512 &msg,
3513 question.entry_name(),
3514 service,
3515 qtype,
3516 intf_addrs,
3517 );
3518 }
3519 }
3520
3521 if delayed && out.answers_count() > 0 {
3523 out.set_id(msg.id());
3524 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3525 let delay =
3526 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
3527 let next_time = current_time_millis() + delay;
3528 self.delayed_responses.push(DelayedResponse {
3529 next_time,
3530 out,
3531 if_index,
3532 is_ipv4,
3533 });
3534 self.add_timer(next_time);
3535 return;
3536 }
3537
3538 if out.answers_count() > 0 {
3539 out.set_id(msg.id());
3540
3541 let matched_source = intf
3544 .addrs
3545 .iter()
3546 .find(|if_addr| valid_ip_on_intf(&querier_ip, if_addr));
3547
3548 let unicast_dest = if querier_addr.port() != MDNS_PORT {
3556 Some(querier_addr)
3557 } else {
3558 None
3559 };
3560
3561 if unicast_dest.is_some() {
3562 for q in msg.questions() {
3563 out.add_question(q.entry_name(), q.entry_type());
3564 }
3565 out.clear_cache_flush_bits();
3566 } else if msg.num_authorities() == 0 {
3567 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3574 }
3575
3576 if out.answers_count() > 0 {
3577 debug!("sending response on intf {}", &intf.name);
3578 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_dns_outgoing(
3579 &out,
3580 intf,
3581 &sock.pktinfo,
3582 self.port,
3583 matched_source,
3584 unicast_dest,
3585 ) {
3586 let invalid_intf_addr = HashSet::from([intf_addr]);
3587 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3588 }
3589
3590 let if_name = intf.name.clone();
3591
3592 self.increase_counter(Counter::Respond, 1);
3593 self.notify_monitors(DaemonEvent::Respond(if_name));
3594 }
3595 }
3596
3597 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3598 }
3599
3600 fn send_delayed_response(&mut self, resp: DelayedResponse) {
3609 let DelayedResponse {
3610 mut out,
3611 if_index,
3612 is_ipv4,
3613 ..
3614 } = resp;
3615
3616 let sock_opt = if is_ipv4 {
3617 &self.ipv4_sock
3618 } else {
3619 &self.ipv6_sock
3620 };
3621 let Some(sock) = sock_opt.as_ref() else {
3622 debug!("send_delayed_response: socket not available for intf {if_index}");
3623 return;
3624 };
3625
3626 if let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) {
3627 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3628 }
3629 if out.answers_count() == 0 {
3630 return;
3631 }
3632
3633 let Some(intf) = self.my_intfs.get(&if_index) else {
3634 debug!("send_delayed_response: no intf found for index {if_index}");
3635 return;
3636 };
3637
3638 let if_name = intf.name.clone();
3639 debug!("sending delayed response on intf {}", &if_name);
3640 let send_result = send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None);
3641
3642 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_result {
3643 let invalid_intf_addr = HashSet::from([intf_addr]);
3644 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3645 }
3646
3647 self.increase_counter(Counter::Respond, 1);
3648 self.notify_monitors(DaemonEvent::Respond(if_name));
3649 }
3650
3651 fn increase_counter(&mut self, counter: Counter, count: i64) {
3653 let key = counter.to_string();
3654 match self.counters.get_mut(&key) {
3655 Some(v) => *v += count,
3656 None => {
3657 self.counters.insert(key, count);
3658 }
3659 }
3660 }
3661
3662 fn set_counter(&mut self, counter: Counter, count: i64) {
3664 let key = counter.to_string();
3665 self.counters.insert(key, count);
3666 }
3667
3668 fn signal_sock_drain(&self) {
3669 let mut signal_buf = [0; 1024];
3670
3671 while let Ok(sz) = self.signal_sock.recv(&mut signal_buf) {
3673 trace!(
3674 "signal socket recvd: {}",
3675 String::from_utf8_lossy(&signal_buf[0..sz])
3676 );
3677 }
3678 }
3679
3680 fn add_retransmission(&mut self, next_time: u64, command: Command) {
3681 self.retransmissions.push(ReRun { next_time, command });
3682 self.add_timer(next_time);
3683 }
3684
3685 fn notify_service_removal(&self, expired: HashMap<String, HashSet<String>>) {
3688 for (ty_domain, sender) in self.service_queriers.iter() {
3689 if let Some(instances) = expired.get(ty_domain) {
3690 for instance_name in instances {
3691 let event = ServiceEvent::ServiceRemoved(
3692 ty_domain.to_string(),
3693 instance_name.to_string(),
3694 );
3695 match sender.send(event) {
3696 Ok(()) => debug!("notify_service_removal: sent ServiceRemoved to listener of {ty_domain}: {instance_name}"),
3697 Err(e) => debug!("Failed to send event: {}", e),
3698 }
3699 }
3700 }
3701 }
3702 }
3703
3704 fn exec_command(&mut self, command: Command, repeating: bool) {
3708 trace!("exec_command: {:?} repeating: {}", &command, repeating);
3709 match command {
3710 Command::Browse(ty, next_delay, cache_only, listener) => {
3711 self.exec_command_browse(repeating, ty, next_delay, cache_only, listener);
3712 }
3713
3714 Command::ResolveHostname(hostname, next_delay, listener, timeout) => {
3715 self.exec_command_resolve_hostname(
3716 repeating, hostname, next_delay, listener, timeout,
3717 );
3718 }
3719
3720 Command::Register(service_info) => {
3721 self.register_service(*service_info);
3722 self.increase_counter(Counter::Register, 1);
3723 }
3724
3725 Command::RegisterResend(fullname, intf) => {
3726 trace!("register-resend service: {fullname} on {}", &intf);
3727 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
3728 self.exec_command_register_resend(fullname, intf)
3729 {
3730 let invalid_intf_addr = HashSet::from([intf_addr]);
3731 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3732 }
3733 }
3734
3735 Command::Unregister(fullname, resp_s) => {
3736 trace!("unregister service {} repeat {}", &fullname, &repeating);
3737 self.exec_command_unregister(repeating, fullname, resp_s);
3738 }
3739
3740 Command::UnregisterResend(packet, if_index, is_ipv4) => {
3741 self.exec_command_unregister_resend(packet, if_index, is_ipv4);
3742 }
3743
3744 Command::StopBrowse(ty_domain) => self.exec_command_stop_browse(ty_domain),
3745
3746 Command::StopResolveHostname(hostname) => {
3747 self.exec_command_stop_resolve_hostname(hostname.to_lowercase())
3748 }
3749
3750 Command::Resolve(instance, try_count) => self.exec_command_resolve(instance, try_count),
3751
3752 Command::GetMetrics(resp_s) => self.exec_command_get_metrics(resp_s),
3753
3754 Command::GetStatus(resp_s) => match resp_s.send(self.status.clone()) {
3755 Ok(()) => trace!("Sent status to the client"),
3756 Err(e) => debug!("Failed to send status: {}", e),
3757 },
3758
3759 Command::Monitor(resp_s) => {
3760 self.monitors.push(resp_s);
3761 }
3762
3763 Command::SetOption(daemon_opt) => {
3764 self.process_set_option(daemon_opt);
3765 }
3766
3767 Command::GetOption(resp_s) => {
3768 let val = DaemonOptionVal {
3769 _service_name_len_max: self.service_name_len_max,
3770 ip_check_interval: self.ip_check_interval,
3771 };
3772 if let Err(e) = resp_s.send(val) {
3773 debug!("Failed to send options: {}", e);
3774 }
3775 }
3776
3777 Command::Verify(instance_fullname, timeout) => {
3778 self.exec_command_verify(instance_fullname, timeout, repeating);
3779 }
3780
3781 Command::InvalidIntfAddrs(invalid_intf_addrs) => {
3782 for intf_addr in invalid_intf_addrs {
3783 self.del_interface_addr(&intf_addr);
3784 }
3785
3786 self.check_ip_changes();
3787 }
3788
3789 _ => {
3790 debug!("unexpected command: {:?}", &command);
3791 }
3792 }
3793 }
3794
3795 fn exec_command_get_metrics(&mut self, resp_s: Sender<HashMap<String, i64>>) {
3796 self.set_counter(Counter::CachedPTR, self.cache.ptr_count() as i64);
3797 self.set_counter(Counter::CachedSRV, self.cache.srv_count() as i64);
3798 self.set_counter(Counter::CachedAddr, self.cache.addr_count() as i64);
3799 self.set_counter(Counter::CachedTxt, self.cache.txt_count() as i64);
3800 self.set_counter(Counter::CachedNSec, self.cache.nsec_count() as i64);
3801 self.set_counter(Counter::CachedSubtype, self.cache.subtype_count() as i64);
3802 self.set_counter(Counter::Timer, self.timers.len() as i64);
3803
3804 let dns_registry_probe_count: usize = self
3805 .dns_registry_map
3806 .values()
3807 .map(|r| r.probing.len())
3808 .sum();
3809 self.set_counter(Counter::DnsRegistryProbe, dns_registry_probe_count as i64);
3810
3811 let dns_registry_active_count: usize = self
3812 .dns_registry_map
3813 .values()
3814 .map(|r| r.active.values().map(|a| a.len()).sum::<usize>())
3815 .sum();
3816 self.set_counter(Counter::DnsRegistryActive, dns_registry_active_count as i64);
3817
3818 let dns_registry_timer_count: usize = self
3819 .dns_registry_map
3820 .values()
3821 .map(|r| r.new_timers.len())
3822 .sum();
3823 self.set_counter(Counter::DnsRegistryTimer, dns_registry_timer_count as i64);
3824
3825 let dns_registry_name_change_count: usize = self
3826 .dns_registry_map
3827 .values()
3828 .map(|r| r.name_changes.len())
3829 .sum();
3830 self.set_counter(
3831 Counter::DnsRegistryNameChange,
3832 dns_registry_name_change_count as i64,
3833 );
3834
3835 if let Err(e) = resp_s.send(self.counters.clone()) {
3837 debug!("Failed to send metrics: {}", e);
3838 }
3839 }
3840
3841 fn exec_command_browse(
3842 &mut self,
3843 repeating: bool,
3844 ty: String,
3845 next_delay: u32,
3846 cache_only: bool,
3847 listener: Sender<ServiceEvent>,
3848 ) {
3849 let pretty_addrs: Vec<String> = self
3850 .my_intfs
3851 .iter()
3852 .map(|(if_index, itf)| format!("{} ({if_index})", itf.name))
3853 .collect();
3854
3855 if let Err(e) = listener.send(ServiceEvent::SearchStarted(format!(
3856 "{ty} on {} interfaces [{}]",
3857 pretty_addrs.len(),
3858 pretty_addrs.join(", ")
3859 ))) {
3860 debug!(
3861 "Failed to send SearchStarted({})(repeating:{}): {}",
3862 &ty, repeating, e
3863 );
3864 return;
3865 }
3866
3867 let now = current_time_millis();
3868 if !repeating {
3869 self.service_queriers.insert(ty.clone(), listener.clone());
3873
3874 self.query_cache_for_service(&ty, &listener, now);
3876 }
3877
3878 if cache_only {
3879 match listener.send(ServiceEvent::SearchStopped(ty.clone())) {
3881 Ok(()) => debug!("SearchStopped sent for {}", &ty),
3882 Err(e) => debug!("Failed to send SearchStopped: {}", e),
3883 }
3884 return;
3885 }
3886
3887 if !repeating {
3888 let jitter =
3890 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3891 self.add_retransmission(now + jitter, Command::Browse(ty, 1, cache_only, listener));
3892 return;
3893 }
3894
3895 self.send_query(&ty, RRType::PTR);
3896 self.increase_counter(Counter::Browse, 1);
3897
3898 let next_time = now + (next_delay * 1000) as u64;
3899 let max_delay = 60 * 60;
3900 let delay = cmp::min(next_delay * 2, max_delay);
3901 self.add_retransmission(next_time, Command::Browse(ty, delay, cache_only, listener));
3902 }
3903
3904 fn exec_command_resolve_hostname(
3905 &mut self,
3906 repeating: bool,
3907 hostname: String,
3908 next_delay: u32,
3909 listener: Sender<HostnameResolutionEvent>,
3910 timeout: Option<u64>,
3911 ) {
3912 let addr_list: Vec<_> = self.my_intfs.iter().collect();
3913 if let Err(e) = listener.send(HostnameResolutionEvent::SearchStarted(format!(
3914 "{} on addrs {:?}",
3915 &hostname, &addr_list
3916 ))) {
3917 debug!(
3918 "Failed to send ResolveStarted({})(repeating:{}): {}",
3919 &hostname, repeating, e
3920 );
3921 return;
3922 }
3923 let now = current_time_millis();
3924 if !repeating {
3925 self.add_hostname_resolver(hostname.to_owned(), listener.clone(), timeout);
3926 self.query_cache_for_hostname(&hostname, listener.clone());
3928
3929 let jitter =
3931 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3932 self.add_retransmission(
3933 now + jitter,
3934 Command::ResolveHostname(hostname, 1, listener, None),
3935 );
3936 return;
3937 }
3938
3939 self.send_query_vec(&[(&hostname, RRType::A), (&hostname, RRType::AAAA)]);
3940 self.increase_counter(Counter::ResolveHostname, 1);
3941
3942 let next_time = now + u64::from(next_delay) * 1000;
3943 let max_delay = 60 * 60;
3944 let delay = cmp::min(next_delay * 2, max_delay);
3945
3946 if self
3948 .hostname_resolvers
3949 .get(&hostname)
3950 .and_then(|(_sender, timeout)| *timeout)
3951 .map(|timeout| next_time < timeout)
3952 .unwrap_or(true)
3953 {
3954 self.add_retransmission(
3955 next_time,
3956 Command::ResolveHostname(hostname, delay, listener, None),
3957 );
3958 }
3959 }
3960
3961 fn exec_command_resolve(&mut self, instance: String, try_count: u16) {
3962 let pending_query = self.query_unresolved(&instance);
3963 let max_try = 3;
3964 if pending_query && try_count < max_try {
3965 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
3968 self.add_retransmission(next_time, Command::Resolve(instance, try_count + 1));
3969 }
3970 }
3971
3972 fn exec_command_unregister(
3973 &mut self,
3974 repeating: bool,
3975 fullname: String,
3976 resp_s: Sender<UnregisterStatus>,
3977 ) {
3978 let response = match self.my_services.remove_entry(&fullname) {
3979 None => {
3980 debug!("unregister: cannot find such service {}", &fullname);
3981 UnregisterStatus::NotFound
3982 }
3983 Some((_k, info)) => {
3984 let mut timers = Vec::new();
3985
3986 for (if_index, intf) in self.my_intfs.iter() {
3987 if let Some(sock) = self.ipv4_sock.as_ref() {
3988 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
3989 if !repeating && !packet.is_empty() {
3991 let next_time = current_time_millis() + 120;
3992 self.retransmissions.push(ReRun {
3993 next_time,
3994 command: Command::UnregisterResend(packet, *if_index, true),
3995 });
3996 timers.push(next_time);
3997 }
3998 }
3999
4000 if let Some(sock) = self.ipv6_sock.as_ref() {
4002 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
4003 if !repeating && !packet.is_empty() {
4004 let next_time = current_time_millis() + 120;
4005 self.retransmissions.push(ReRun {
4006 next_time,
4007 command: Command::UnregisterResend(packet, *if_index, false),
4008 });
4009 timers.push(next_time);
4010 }
4011 }
4012 }
4013
4014 for t in timers {
4015 self.add_timer(t);
4016 }
4017
4018 self.increase_counter(Counter::Unregister, 1);
4019 UnregisterStatus::OK
4020 }
4021 };
4022 if let Err(e) = resp_s.send(response) {
4023 debug!("unregister: failed to send response: {}", e);
4024 }
4025 }
4026
4027 fn exec_command_unregister_resend(&mut self, packet: Vec<u8>, if_index: u32, is_ipv4: bool) {
4028 let Some(intf) = self.my_intfs.get(&if_index) else {
4029 return;
4030 };
4031 let sock_opt = if is_ipv4 {
4032 &self.ipv4_sock
4033 } else {
4034 &self.ipv6_sock
4035 };
4036 let Some(sock) = sock_opt else {
4037 return;
4038 };
4039
4040 let if_addr = if is_ipv4 {
4041 match intf.next_ifaddr_v4() {
4042 Some(addr) => addr,
4043 None => return,
4044 }
4045 } else {
4046 match intf.next_ifaddr_v6() {
4047 Some(addr) => addr,
4048 None => return,
4049 }
4050 };
4051
4052 debug!("UnregisterResend from {:?}", if_addr);
4053 multicast_on_intf(
4054 &packet[..],
4055 &intf.name,
4056 intf.index,
4057 if_addr,
4058 &sock.pktinfo,
4059 self.port,
4060 );
4061
4062 self.increase_counter(Counter::UnregisterResend, 1);
4063 }
4064
4065 fn exec_command_stop_browse(&mut self, ty_domain: String) {
4066 match self.service_queriers.remove_entry(&ty_domain) {
4067 None => debug!("StopBrowse: cannot find querier for {}", &ty_domain),
4068 Some((ty, sender)) => {
4069 trace!("StopBrowse: removed queryer for {}", &ty);
4071 let mut i = 0;
4072 while i < self.retransmissions.len() {
4073 if let Command::Browse(t, _, _, _) = &self.retransmissions[i].command {
4074 if t == &ty {
4075 self.retransmissions.remove(i);
4076 trace!("StopBrowse: removed retransmission for {}", &ty);
4077 continue;
4078 }
4079 }
4080 i += 1;
4081 }
4082
4083 self.cache.remove_service_type(&ty_domain);
4085
4086 match sender.send(ServiceEvent::SearchStopped(ty_domain)) {
4088 Ok(()) => trace!("Sent SearchStopped to the listener"),
4089 Err(e) => debug!("Failed to send SearchStopped: {}", e),
4090 }
4091 }
4092 }
4093 }
4094
4095 fn exec_command_stop_resolve_hostname(&mut self, hostname: String) {
4096 if let Some((host, (sender, _timeout))) = self.hostname_resolvers.remove_entry(&hostname) {
4097 trace!("StopResolve: removed queryer for {}", &host);
4099 let mut i = 0;
4100 while i < self.retransmissions.len() {
4101 if let Command::Resolve(t, _) = &self.retransmissions[i].command {
4102 if t == &host {
4103 self.retransmissions.remove(i);
4104 trace!("StopResolve: removed retransmission for {}", &host);
4105 continue;
4106 }
4107 }
4108 i += 1;
4109 }
4110
4111 match sender.send(HostnameResolutionEvent::SearchStopped(hostname)) {
4113 Ok(()) => trace!("Sent SearchStopped to the listener"),
4114 Err(e) => debug!("Failed to send SearchStopped: {}", e),
4115 }
4116 }
4117 }
4118
4119 fn exec_command_register_resend(&mut self, fullname: String, if_index: u32) -> MyResult<()> {
4120 let Some(info) = self.my_services.get_mut(&fullname) else {
4121 trace!("announce: cannot find such service {}", &fullname);
4122 return Ok(());
4123 };
4124
4125 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
4126 return Ok(());
4127 };
4128
4129 let Some(intf) = self.my_intfs.get(&if_index) else {
4130 return Ok(());
4131 };
4132
4133 let announced_v4 = if let Some(sock) = self.ipv4_sock.as_ref() {
4134 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
4135 } else {
4136 false
4137 };
4138 let announced_v6 = if let Some(sock) = self.ipv6_sock.as_ref() {
4139 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
4140 } else {
4141 false
4142 };
4143
4144 if announced_v4 || announced_v6 {
4145 let hostname = dns_registry.resolve_name(info.get_hostname());
4146 let service_name = dns_registry.resolve_name(&fullname).to_string();
4147
4148 debug!("resend: announce service {service_name} on {}", intf.name);
4149
4150 notify_monitors(
4151 &mut self.monitors,
4152 DaemonEvent::Announce(service_name, format!("{}:{}", hostname, &intf.name)),
4153 );
4154 info.set_status(if_index, ServiceStatus::Announced);
4155 } else {
4156 debug!("register-resend should not fail");
4157 }
4158
4159 self.increase_counter(Counter::RegisterResend, 1);
4160 Ok(())
4161 }
4162
4163 fn exec_command_verify(&mut self, instance: String, timeout: Duration, repeating: bool) {
4164 let now = current_time_millis();
4174 let expire_at = if repeating {
4175 None
4176 } else {
4177 Some(now + timeout.as_millis() as u64)
4178 };
4179
4180 let record_vec = self.cache.service_verify_queries(&instance, expire_at);
4182
4183 if !record_vec.is_empty() {
4184 let query_vec: Vec<(&str, RRType)> = record_vec
4185 .iter()
4186 .map(|(record, rr_type)| (record.as_str(), *rr_type))
4187 .collect();
4188 self.send_query_vec(&query_vec);
4189
4190 if let Some(new_expire) = expire_at {
4191 self.add_timer(new_expire); self.add_retransmission(now + 1000, Command::Verify(instance, timeout));
4195 }
4196 }
4197 }
4198
4199 fn refresh_active_services(&mut self) {
4201 let mut query_ptr_count = 0;
4202 let mut query_srv_count = 0;
4203 let mut new_timers = HashSet::new();
4204 let mut query_addr_count = 0;
4205
4206 for (ty_domain, _sender) in self.service_queriers.iter() {
4207 let refreshed_timers = self.cache.refresh_due_ptr(ty_domain);
4208 if !refreshed_timers.is_empty() {
4209 trace!("sending refresh query for PTR: {}", ty_domain);
4210 self.send_query(ty_domain, RRType::PTR);
4211 query_ptr_count += 1;
4212 new_timers.extend(refreshed_timers);
4213 }
4214
4215 let (instances, timers) = self.cache.refresh_due_srv_txt(ty_domain);
4216 for (instance, types) in instances {
4217 trace!("sending refresh query for: {}", &instance);
4218 let query_vec = types
4219 .into_iter()
4220 .map(|ty| (instance.as_str(), ty))
4221 .collect::<Vec<_>>();
4222 self.send_query_vec(&query_vec);
4223 query_srv_count += 1;
4224 }
4225 new_timers.extend(timers);
4226 let (hostnames, timers) = self.cache.refresh_due_hosts(ty_domain);
4227 for hostname in hostnames.iter() {
4228 trace!("sending refresh queries for A and AAAA: {}", hostname);
4229 self.send_query_vec(&[(hostname, RRType::A), (hostname, RRType::AAAA)]);
4230 query_addr_count += 2;
4231 }
4232 new_timers.extend(timers);
4233 }
4234
4235 for timer in new_timers {
4236 self.add_timer(timer);
4237 }
4238
4239 self.increase_counter(Counter::CacheRefreshPTR, query_ptr_count);
4240 self.increase_counter(Counter::CacheRefreshSrvTxt, query_srv_count);
4241 self.increase_counter(Counter::CacheRefreshAddr, query_addr_count);
4242 }
4243}
4244
4245fn add_answer_of_service(
4247 out: &mut DnsOutgoing,
4248 msg: &DnsIncoming,
4249 entry_name: &str,
4250 service: &ServiceInfo,
4251 qtype: RRType,
4252 intf_addrs: Vec<IpAddr>,
4253) {
4254 if qtype == RRType::SRV || qtype == RRType::ANY {
4255 out.add_answer(
4256 msg,
4257 DnsSrv::new(
4258 entry_name,
4259 CLASS_IN | CLASS_CACHE_FLUSH,
4260 service.get_host_ttl(),
4261 service.get_priority(),
4262 service.get_weight(),
4263 service.get_port(),
4264 service.get_hostname().to_string(),
4265 ),
4266 );
4267 }
4268
4269 if qtype == RRType::TXT || qtype == RRType::ANY {
4270 out.add_answer(
4271 msg,
4272 DnsTxt::new(
4273 entry_name,
4274 CLASS_IN | CLASS_CACHE_FLUSH,
4275 service.get_other_ttl(),
4276 service.generate_txt(),
4277 ),
4278 );
4279 }
4280
4281 if qtype == RRType::SRV {
4282 for address in intf_addrs {
4283 out.add_additional_answer(DnsAddress::new(
4284 service.get_hostname(),
4285 ip_address_rr_type(&address),
4286 CLASS_IN | CLASS_CACHE_FLUSH,
4287 service.get_host_ttl(),
4288 address,
4289 InterfaceId::default(),
4290 ));
4291 }
4292 }
4293}
4294
4295#[derive(Clone, Debug)]
4298#[non_exhaustive]
4299pub enum ServiceEvent {
4300 SearchStarted(String),
4302
4303 ServiceFound(String, String),
4305
4306 ServiceResolved(Box<ResolvedService>),
4308
4309 ServiceRemoved(String, String),
4311
4312 SearchStopped(String),
4314}
4315
4316#[derive(Clone, Debug)]
4319#[non_exhaustive]
4320pub enum HostnameResolutionEvent {
4321 SearchStarted(String),
4323 AddressesFound(String, HashSet<ScopedIp>),
4325 AddressesRemoved(String, HashSet<ScopedIp>),
4327 SearchTimeout(String),
4329 SearchStopped(String),
4331}
4332
4333#[derive(Clone, Debug)]
4336#[non_exhaustive]
4337pub enum DaemonEvent {
4338 Announce(String, String),
4340
4341 Error(Error),
4343
4344 IpAdd(IpAddr),
4346
4347 IpDel(IpAddr),
4349
4350 NameChange(DnsNameChange),
4353
4354 Respond(String),
4356}
4357
4358#[derive(Clone, Debug)]
4361pub struct DnsNameChange {
4362 pub original: String,
4364
4365 pub new_name: String,
4375
4376 pub rr_type: RRType,
4378
4379 pub intf_name: String,
4381}
4382
4383#[derive(Debug)]
4385enum Command {
4386 Browse(String, u32, bool, Sender<ServiceEvent>),
4388
4389 ResolveHostname(String, u32, Sender<HostnameResolutionEvent>, Option<u64>), Register(Box<ServiceInfo>),
4394
4395 Unregister(String, Sender<UnregisterStatus>), RegisterResend(String, u32), UnregisterResend(Vec<u8>, u32, bool), StopBrowse(String), StopResolveHostname(String), Resolve(String, u16), GetMetrics(Sender<Metrics>),
4416
4417 GetStatus(Sender<DaemonStatus>),
4419
4420 Monitor(Sender<DaemonEvent>),
4422
4423 SetOption(DaemonOption),
4424
4425 GetOption(Sender<DaemonOptionVal>),
4426
4427 Verify(String, Duration),
4432
4433 InvalidIntfAddrs(HashSet<Interface>),
4435
4436 Exit(Sender<DaemonStatus>),
4437}
4438
4439impl fmt::Display for Command {
4440 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4441 match self {
4442 Self::Browse(_, _, _, _) => write!(f, "Command Browse"),
4443 Self::ResolveHostname(_, _, _, _) => write!(f, "Command ResolveHostname"),
4444 Self::Exit(_) => write!(f, "Command Exit"),
4445 Self::GetStatus(_) => write!(f, "Command GetStatus"),
4446 Self::GetMetrics(_) => write!(f, "Command GetMetrics"),
4447 Self::Monitor(_) => write!(f, "Command Monitor"),
4448 Self::Register(_) => write!(f, "Command Register"),
4449 Self::RegisterResend(_, _) => write!(f, "Command RegisterResend"),
4450 Self::SetOption(_) => write!(f, "Command SetOption"),
4451 Self::GetOption(_) => write!(f, "Command GetOption"),
4452 Self::StopBrowse(_) => write!(f, "Command StopBrowse"),
4453 Self::StopResolveHostname(_) => write!(f, "Command StopResolveHostname"),
4454 Self::Unregister(_, _) => write!(f, "Command Unregister"),
4455 Self::UnregisterResend(_, _, _) => write!(f, "Command UnregisterResend"),
4456 Self::Resolve(_, _) => write!(f, "Command Resolve"),
4457 Self::Verify(_, _) => write!(f, "Command VerifyResource"),
4458 Self::InvalidIntfAddrs(_) => write!(f, "Command InvalidIntfAddrs"),
4459 }
4460 }
4461}
4462
4463struct DaemonOptionVal {
4464 _service_name_len_max: u8,
4465 ip_check_interval: u64,
4466}
4467
4468#[derive(Debug)]
4469enum DaemonOption {
4470 ServiceNameLenMax(u8),
4471 IpCheckInterval(u64),
4472 MaxPacketSize(Vec<IfKind>, usize),
4473 EnableInterface(Vec<IfKind>),
4474 DisableInterface(Vec<IfKind>),
4475 MulticastLoopV4(bool),
4476 MulticastLoopV6(bool),
4477 AcceptUnsolicited(bool),
4478 IncludeAppleP2P(bool),
4479 #[cfg(test)]
4480 TestDownInterface(String),
4481 #[cfg(test)]
4482 TestUpInterface(String),
4483}
4484
4485const DOMAIN_LEN: usize = "._tcp.local.".len();
4487
4488fn check_service_name_length(ty_domain: &str, limit: u8) -> Result<()> {
4490 if ty_domain.len() <= DOMAIN_LEN + 1 {
4491 return Err(e_fmt!("Service type name cannot be empty: {}", ty_domain));
4493 }
4494
4495 let service_name_len = ty_domain.len() - DOMAIN_LEN - 1; if service_name_len > limit as usize {
4497 return Err(e_fmt!("Service name length must be <= {} bytes", limit));
4498 }
4499 Ok(())
4500}
4501
4502fn check_domain_suffix(name: &str) -> Result<()> {
4504 if !(name.ends_with("._tcp.local.") || name.ends_with("._udp.local.")) {
4505 return Err(e_fmt!(
4506 "mDNS service {} must end with '._tcp.local.' or '._udp.local.'",
4507 name
4508 ));
4509 }
4510
4511 Ok(())
4512}
4513
4514fn check_service_name(fullname: &str) -> Result<()> {
4522 check_domain_suffix(fullname)?;
4523
4524 let remaining: Vec<&str> = fullname[..fullname.len() - DOMAIN_LEN].split('.').collect();
4525 let name = remaining.last().ok_or_else(|| e_fmt!("No service name"))?;
4526
4527 if &name[0..1] != "_" {
4528 return Err(e_fmt!("Service name must start with '_'"));
4529 }
4530
4531 let name = &name[1..];
4532
4533 if name.contains("--") {
4534 return Err(e_fmt!("Service name must not contain '--'"));
4535 }
4536
4537 if name.starts_with('-') || name.ends_with('-') {
4538 return Err(e_fmt!("Service name (%s) may not start or end with '-'"));
4539 }
4540
4541 let ascii_count = name.chars().filter(|c| c.is_ascii_alphabetic()).count();
4542 if ascii_count < 1 {
4543 return Err(e_fmt!(
4544 "Service name must contain at least one letter (eg: 'A-Za-z')"
4545 ));
4546 }
4547
4548 Ok(())
4549}
4550
4551fn check_hostname(hostname: &str) -> Result<()> {
4553 if !hostname.ends_with(".local.") {
4554 return Err(e_fmt!("Hostname must end with '.local.': {hostname}"));
4555 }
4556
4557 if hostname == ".local." {
4558 return Err(e_fmt!(
4559 "The part of the hostname before '.local.' cannot be empty"
4560 ));
4561 }
4562
4563 if hostname.len() > 255 {
4564 return Err(e_fmt!("Hostname length must be <= 255 bytes"));
4565 }
4566
4567 Ok(())
4568}
4569
4570fn call_service_listener(
4571 listeners_map: &HashMap<String, Sender<ServiceEvent>>,
4572 ty_domain: &str,
4573 event: ServiceEvent,
4574) {
4575 if let Some(listener) = listeners_map.get(ty_domain) {
4576 match listener.send(event) {
4577 Ok(()) => trace!("Sent event to listener successfully"),
4578 Err(e) => debug!("Failed to send event: {}", e),
4579 }
4580 }
4581}
4582
4583fn call_hostname_resolution_listener(
4584 listeners_map: &HashMap<String, (Sender<HostnameResolutionEvent>, Option<u64>)>,
4585 hostname: &str,
4586 event: HostnameResolutionEvent,
4587) {
4588 let hostname_lower = hostname.to_lowercase();
4589 if let Some(listener) = listeners_map.get(&hostname_lower).map(|(l, _)| l) {
4590 match listener.send(event) {
4591 Ok(()) => trace!("Sent event to listener successfully"),
4592 Err(e) => debug!("Failed to send event: {}", e),
4593 }
4594 }
4595}
4596
4597fn my_ip_interfaces(with_loopback: bool) -> Vec<Interface> {
4601 my_ip_interfaces_inner(with_loopback, false)
4602}
4603
4604fn my_ip_interfaces_inner(with_loopback: bool, with_apple_p2p: bool) -> Vec<Interface> {
4605 if_addrs::get_if_addrs()
4606 .unwrap_or_default()
4607 .into_iter()
4608 .filter(|i| {
4609 i.is_oper_up()
4610 && !i.is_p2p()
4611 && (!i.is_loopback() || with_loopback)
4612 && (with_apple_p2p || !is_apple_p2p_by_name(&i.name))
4613 })
4614 .collect()
4615}
4616
4617fn is_apple_p2p_by_name(name: &str) -> bool {
4620 let p2p_prefixes = ["awdl", "llw"];
4621 p2p_prefixes.iter().any(|prefix| name.starts_with(prefix))
4622}
4623
4624#[derive(Clone, Copy, Debug)]
4626struct SendConfig {
4627 port: u16,
4629
4630 max_packet_size: usize,
4633
4634 is_ipv4: bool,
4637}
4638
4639fn send_dns_outgoing(
4642 out: &DnsOutgoing,
4643 my_intf: &MyIntf,
4644 sock: &PktInfoUdpSocket,
4645 port: u16,
4646 source: Option<&IfAddr>,
4647 unicast_dest: Option<SocketAddr>,
4648) -> MyResult<Vec<Vec<u8>>> {
4649 let if_name = &my_intf.name;
4650
4651 let if_addr = match source {
4652 Some(addr) => addr,
4653 None => {
4654 if sock.domain() == Domain::IPV4 {
4655 match my_intf.next_ifaddr_v4() {
4656 Some(addr) => addr,
4657 None => return Ok(vec![]),
4658 }
4659 } else {
4660 match my_intf.next_ifaddr_v6() {
4661 Some(addr) => addr,
4662 None => return Ok(vec![]),
4663 }
4664 }
4665 }
4666 };
4667
4668 let is_ipv4 = if_addr.ip().is_ipv4();
4670 let config = SendConfig {
4671 port,
4672 max_packet_size: my_intf.max_packet_size(is_ipv4),
4673 is_ipv4,
4674 };
4675
4676 send_dns_outgoing_impl(
4677 out,
4678 if_name,
4679 my_intf.index,
4680 if_addr,
4681 sock,
4682 config,
4683 unicast_dest,
4684 )
4685}
4686
4687fn send_dns_outgoing_impl(
4689 out: &DnsOutgoing,
4690 if_name: &str,
4691 if_index: u32,
4692 if_addr: &IfAddr,
4693 sock: &PktInfoUdpSocket,
4694 config: SendConfig,
4695 unicast_dest: Option<SocketAddr>,
4696) -> MyResult<Vec<Vec<u8>>> {
4697 let qtype = if out.is_query() {
4698 "query"
4699 } else {
4700 if out.answers_count() == 0 && out.additionals().is_empty() {
4701 return Ok(vec![]); }
4703 "response"
4704 };
4705 trace!(
4706 "send {}: {} questions {} answers {} authorities {} additional",
4707 qtype,
4708 out.questions().len(),
4709 out.answers_count(),
4710 out.authorities().len(),
4711 out.additionals().len()
4712 );
4713
4714 match if_addr.ip() {
4715 IpAddr::V4(ipv4) => {
4716 if let Err(e) = sock.set_multicast_if_v4(&ipv4) {
4717 debug!(
4718 "send_dns_outgoing: failed to set multicast interface for IPv4 {}: {}",
4719 ipv4, e
4720 );
4721 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4723 let intf_addr = Interface {
4724 name: if_name.to_string(),
4725 addr: if_addr.clone(),
4726 index: Some(if_index),
4727 oper_status: if_addrs::IfOperStatus::Down,
4728 is_p2p: false,
4729 #[cfg(windows)]
4730 adapter_name: String::new(),
4731 };
4732 return Err(InternalError::IntfAddrInvalid(intf_addr));
4733 }
4734 return Ok(vec![]); }
4736 }
4737 IpAddr::V6(ipv6) => {
4738 if let Err(e) = sock.set_multicast_if_v6(if_index) {
4739 debug!(
4740 "send_dns_outgoing: failed to set multicast interface for IPv6 {}: {}",
4741 ipv6, e
4742 );
4743 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4745 let intf_addr = Interface {
4746 name: if_name.to_string(),
4747 addr: if_addr.clone(),
4748 index: Some(if_index),
4749 oper_status: if_addrs::IfOperStatus::Down,
4750 is_p2p: false,
4751 #[cfg(windows)]
4752 adapter_name: String::new(),
4753 };
4754 return Err(InternalError::IntfAddrInvalid(intf_addr));
4755 }
4756 return Ok(vec![]); }
4758 }
4759 }
4760
4761 let packet_list = out.to_data_on_wire(config.max_packet_size, config.is_ipv4);
4762 for packet in packet_list.iter() {
4763 match unicast_dest {
4764 Some(dest) => unicast_on_intf(packet, if_name, dest, sock),
4765 None => multicast_on_intf(packet, if_name, if_index, if_addr, sock, config.port),
4766 }
4767 }
4768 Ok(packet_list)
4769}
4770
4771fn unicast_on_intf(packet: &[u8], if_name: &str, dest: SocketAddr, socket: &PktInfoUdpSocket) {
4774 let max_size = max_pkt_absolute(dest.is_ipv4());
4775 if packet.len() > max_size {
4776 debug!("Drop over-sized packet ({} > {max_size})", packet.len());
4777 return;
4778 }
4779
4780 let sock_addr = dest.into();
4781 match socket.send_to(packet, &sock_addr) {
4782 Ok(sz) => trace!(
4783 "sent unicast {} bytes on interface {} to {}",
4784 sz,
4785 if_name,
4786 dest
4787 ),
4788 Err(e) => trace!(
4789 "Failed to send unicast to {} via {:?}: {}",
4790 dest,
4791 &if_name,
4792 e
4793 ),
4794 }
4795}
4796
4797fn multicast_on_intf(
4799 packet: &[u8],
4800 if_name: &str,
4801 if_index: u32,
4802 if_addr: &IfAddr,
4803 socket: &PktInfoUdpSocket,
4804 port: u16,
4805) {
4806 let max_size = max_pkt_absolute(if_addr.ip().is_ipv4());
4807 if packet.len() > max_size {
4808 debug!("Drop over-sized packet ({} > {max_size})", packet.len());
4809 return;
4810 }
4811
4812 let addr: SocketAddr = match if_addr {
4813 if_addrs::IfAddr::V4(_) => SocketAddrV4::new(GROUP_ADDR_V4, port).into(),
4814 if_addrs::IfAddr::V6(_) => {
4815 let mut sock = SocketAddrV6::new(GROUP_ADDR_V6, port, 0, 0);
4816 sock.set_scope_id(if_index); sock.into()
4818 }
4819 };
4820
4821 let sock_addr = addr.into();
4823 match socket.send_to(packet, &sock_addr) {
4824 Ok(sz) => trace!(
4825 "sent out {} bytes on interface {} (idx {}) addr {}",
4826 sz,
4827 if_name,
4828 if_index,
4829 if_addr.ip()
4830 ),
4831 Err(e) => trace!("Failed to send to {} via {:?}: {}", addr, &if_name, e),
4832 }
4833}
4834
4835fn valid_instance_name(name: &str) -> bool {
4839 name.split('.').count() >= 5
4840}
4841
4842fn notify_monitors(monitors: &mut Vec<Sender<DaemonEvent>>, event: DaemonEvent) {
4843 monitors.retain(|sender| {
4844 if let Err(e) = sender.try_send(event.clone()) {
4845 debug!("notify_monitors: try_send: {}", &e);
4846 if matches!(e, TrySendError::Disconnected(_)) {
4847 return false; }
4849 }
4850 true
4851 });
4852}
4853
4854fn prepare_announce(
4857 info: &ServiceInfo,
4858 intf: &MyIntf,
4859 dns_registry: &mut DnsRegistry,
4860 is_ipv4: bool,
4861) -> Option<DnsOutgoing> {
4862 let intf_addrs = if is_ipv4 {
4863 info.get_addrs_on_my_intf_v4(intf)
4864 } else {
4865 info.get_addrs_on_my_intf_v6(intf)
4866 };
4867
4868 if intf_addrs.is_empty() {
4869 debug!(
4870 "prepare_announce (ipv4: {is_ipv4}): no valid addrs on interface {}",
4871 &intf.name
4872 );
4873 return None;
4874 }
4875
4876 let service_fullname = dns_registry.resolve_name(info.get_fullname());
4878
4879 debug!(
4880 "prepare to announce service {service_fullname} on {:?}",
4881 &intf_addrs
4882 );
4883
4884 let mut probing_count = 0;
4885 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
4886 let create_time = current_time_millis() + fastrand::u64(0..250);
4887
4888 out.add_answer_at_time(
4889 DnsPointer::new(
4890 info.get_type(),
4891 RRType::PTR,
4892 CLASS_IN,
4893 info.get_other_ttl(),
4894 service_fullname.to_string(),
4895 ),
4896 0,
4897 );
4898
4899 if let Some(sub) = info.get_subtype() {
4900 trace!("Adding subdomain {}", sub);
4901 out.add_answer_at_time(
4902 DnsPointer::new(
4903 sub,
4904 RRType::PTR,
4905 CLASS_IN,
4906 info.get_other_ttl(),
4907 service_fullname.to_string(),
4908 ),
4909 0,
4910 );
4911 }
4912
4913 let hostname = dns_registry.resolve_name(info.get_hostname()).to_string();
4915
4916 let mut srv = DnsSrv::new(
4917 info.get_fullname(),
4918 CLASS_IN | CLASS_CACHE_FLUSH,
4919 info.get_host_ttl(),
4920 info.get_priority(),
4921 info.get_weight(),
4922 info.get_port(),
4923 hostname,
4924 );
4925
4926 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4927 srv.get_record_mut().set_new_name(new_name.to_string());
4928 }
4929
4930 if !info.requires_probe()
4931 || dns_registry.is_probing_done(&srv, info.get_fullname(), create_time)
4932 {
4933 out.add_answer_at_time(srv, 0);
4934 } else {
4935 probing_count += 1;
4936 }
4937
4938 let mut txt = DnsTxt::new(
4941 info.get_fullname(),
4942 CLASS_IN | CLASS_CACHE_FLUSH,
4943 info.get_other_ttl(),
4944 info.generate_txt(),
4945 );
4946
4947 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4948 txt.get_record_mut().set_new_name(new_name.to_string());
4949 }
4950
4951 if !info.requires_probe()
4952 || dns_registry.is_probing_done(&txt, info.get_fullname(), create_time)
4953 {
4954 out.add_answer_at_time(txt, 0);
4955 } else {
4956 probing_count += 1;
4957 }
4958
4959 let hostname = info.get_hostname();
4962 for address in intf_addrs {
4963 let mut dns_addr = DnsAddress::new(
4964 hostname,
4965 ip_address_rr_type(&address),
4966 CLASS_IN | CLASS_CACHE_FLUSH,
4967 info.get_host_ttl(),
4968 address,
4969 intf.into(),
4970 );
4971
4972 if let Some(new_name) = dns_registry.name_changes.get(hostname) {
4973 dns_addr.get_record_mut().set_new_name(new_name.to_string());
4974 }
4975
4976 if !info.requires_probe()
4977 || dns_registry.is_probing_done(&dns_addr, info.get_fullname(), create_time)
4978 {
4979 out.add_answer_at_time(dns_addr, 0);
4980 } else {
4981 probing_count += 1;
4982 }
4983 }
4984
4985 if probing_count > 0 {
4986 return None;
4987 }
4988
4989 Some(out)
4990}
4991
4992fn announce_service_on_intf(
4995 dns_registry: &mut DnsRegistry,
4996 info: &ServiceInfo,
4997 intf: &MyIntf,
4998 sock: &PktInfoUdpSocket,
4999 port: u16,
5000) -> MyResult<bool> {
5001 let is_ipv4 = sock.domain() == Domain::IPV4;
5002 if let Some(mut out) = prepare_announce(info, intf, dns_registry, is_ipv4) {
5003 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
5006 if out.answers_count() > 0 {
5007 let _ = send_dns_outgoing(&out, intf, sock, port, None, None)?;
5008 }
5009 return Ok(true);
5010 }
5011
5012 Ok(false)
5013}
5014
5015fn name_change(original: &str) -> String {
5023 let mut parts: Vec<_> = original.split('.').collect();
5024 let Some(first_part) = parts.get_mut(0) else {
5025 return format!("{original} (2)");
5026 };
5027
5028 let mut new_name = format!("{first_part} (2)");
5029
5030 if let Some(paren_pos) = first_part.rfind(" (") {
5032 if let Some(end_paren) = first_part[paren_pos..].find(')') {
5034 let absolute_end_pos = paren_pos + end_paren;
5035 if absolute_end_pos == first_part.len() - 1 {
5037 let num_start = paren_pos + 2; if let Ok(number) = first_part[num_start..absolute_end_pos].parse::<u32>() {
5040 let base_name = &first_part[..paren_pos];
5041 new_name = format!("{} ({})", base_name, number + 1)
5042 }
5043 }
5044 }
5045 }
5046
5047 *first_part = &new_name;
5048 parts.join(".")
5049}
5050
5051fn hostname_change(original: &str) -> String {
5059 let mut parts: Vec<_> = original.split('.').collect();
5060 let Some(first_part) = parts.get_mut(0) else {
5061 return format!("{original}-2");
5062 };
5063
5064 let mut new_name = format!("{first_part}-2");
5065
5066 if let Some(hyphen_pos) = first_part.rfind('-') {
5068 if let Ok(number) = first_part[hyphen_pos + 1..].parse::<u32>() {
5070 let base_name = &first_part[..hyphen_pos];
5071 new_name = format!("{}-{}", base_name, number + 1);
5072 }
5073 }
5074
5075 *first_part = &new_name;
5076 parts.join(".")
5077}
5078
5079fn check_probing(
5082 dns_registry: &mut DnsRegistry,
5083 timers: &mut BinaryHeap<Reverse<u64>>,
5084 now: u64,
5085) -> (DnsOutgoing, Vec<String>) {
5086 let mut expired_probes = Vec::new();
5087 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
5088
5089 for (name, probe) in dns_registry.probing.iter_mut() {
5090 if now >= probe.next_send {
5091 if probe.expired(now) {
5092 expired_probes.push(name.clone());
5094 } else {
5095 out.add_question(name, RRType::ANY);
5096
5097 for record in probe.records.iter() {
5105 out.add_authority(record.clone());
5106 }
5107
5108 probe.update_next_send(now);
5109
5110 timers.push(Reverse(probe.next_send));
5112 }
5113 }
5114 }
5115
5116 (out, expired_probes)
5117}
5118
5119fn handle_expired_probes(
5124 expired_probes: Vec<String>,
5125 intf_name: &str,
5126 dns_registry: &mut DnsRegistry,
5127 monitors: &mut Vec<Sender<DaemonEvent>>,
5128) -> HashSet<String> {
5129 let mut waiting_services = HashSet::new();
5130
5131 for name in expired_probes {
5132 let Some(probe) = dns_registry.probing.remove(&name) else {
5133 continue;
5134 };
5135
5136 for record in probe.records.iter() {
5138 if let Some(new_name) = record.get_record().get_new_name() {
5139 dns_registry
5140 .name_changes
5141 .insert(name.clone(), new_name.to_string());
5142
5143 let event = DnsNameChange {
5144 original: record.get_record().get_original_name().to_string(),
5145 new_name: new_name.to_string(),
5146 rr_type: record.get_type(),
5147 intf_name: intf_name.to_string(),
5148 };
5149 debug!("Name change event: {:?}", &event);
5150 notify_monitors(monitors, DaemonEvent::NameChange(event));
5151 }
5152 }
5153
5154 debug!(
5156 "probe of '{name}' finished: move {} records to active. ({} waiting services)",
5157 probe.records.len(),
5158 probe.waiting_services.len(),
5159 );
5160
5161 if !probe.records.is_empty() {
5163 match dns_registry.active.get_mut(&name) {
5164 Some(records) => {
5165 records.extend(probe.records);
5166 }
5167 None => {
5168 dns_registry.active.insert(name, probe.records);
5169 }
5170 }
5171
5172 waiting_services.extend(probe.waiting_services);
5173 }
5174 }
5175
5176 waiting_services
5177}
5178
5179fn resolve_max_packet_size(
5187 selections: &[MaxPacketSizeSelection],
5188 interfaces: &[Interface],
5189 if_index: u32,
5190 is_ipv4: bool,
5191) -> usize {
5192 let mut size = MAX_PKT_DEFAULT;
5193
5194 for selection in selections {
5195 let matched = interfaces.iter().any(|intf| {
5196 intf.index.unwrap_or(0) == if_index
5197 && intf.ip().is_ipv4() == is_ipv4
5198 && selection.if_kind.matches(intf)
5199 });
5200 if matched {
5201 size = selection.max_packet_size;
5202 }
5203 }
5204
5205 size
5206}
5207
5208fn resolve_addr_to_index(if_kind: IfKind, interfaces: &[Interface]) -> IfKind {
5210 if let IfKind::Addr(addr) = &if_kind {
5211 if let Some(intf) = interfaces.iter().find(|intf| &intf.ip() == addr) {
5212 let if_index = intf.index.unwrap_or(0);
5213 return if addr.is_ipv4() {
5214 IfKind::IndexV4(if_index)
5215 } else {
5216 IfKind::IndexV6(if_index)
5217 };
5218 }
5219 }
5220 if_kind
5221}
5222
5223#[cfg(test)]
5224mod tests {
5225 use super::{
5226 _new_socket_bind, check_domain_suffix, check_service_name_length, hostname_change,
5227 my_ip_interfaces, name_change, resolve_max_packet_size, send_dns_outgoing_impl,
5228 valid_instance_name, valid_ip_on_intf, DaemonEvent, HostnameResolutionEvent, IfKind,
5229 MaxPacketSizeSelection, MyIntf, SendConfig, ServiceDaemon, ServiceEvent, ServiceInfo,
5230 GROUP_ADDR_V4, INITIAL_QUERY_DELAY_MAX_MILLIS, INITIAL_QUERY_DELAY_MIN_MILLIS,
5231 MAX_PKT_ABSOLUTE_IPV6, MAX_PKT_DEFAULT, MDNS_PORT, MIN_MAX_PACKET_SIZE,
5232 SHARED_RESPONSE_DELAY_MAX_MILLIS, SHARED_RESPONSE_DELAY_MIN_MILLIS,
5233 };
5234 use crate::{
5235 dns_parser::{
5236 DnsEntryExt, DnsIncoming, DnsOutgoing, DnsPointer, InterfaceId, RRType, ScopedIp,
5237 CLASS_IN, FLAGS_AA, FLAGS_QR_QUERY, FLAGS_QR_RESPONSE,
5238 },
5239 service_daemon::{add_answer_of_service, check_hostname},
5240 };
5241 use if_addrs::{IfAddr, Ifv4Addr, Ifv6Addr, Interface};
5242 use std::{
5243 collections::HashSet,
5244 net::{IpAddr, Ipv4Addr, Ipv6Addr, UdpSocket},
5245 time::{Duration, Instant, SystemTime},
5246 };
5247 use test_log::test;
5248
5249 fn test_interface(name: &str, index: u32, addr: IfAddr) -> Interface {
5251 Interface {
5252 name: name.to_string(),
5253 addr,
5254 index: Some(index),
5255 oper_status: if_addrs::IfOperStatus::Up,
5256 is_p2p: false,
5257 #[cfg(windows)]
5258 adapter_name: String::new(),
5259 }
5260 }
5261
5262 fn test_ifaddr_v4(ip: Ipv4Addr) -> IfAddr {
5263 IfAddr::V4(Ifv4Addr {
5264 ip,
5265 netmask: Ipv4Addr::new(255, 255, 255, 0),
5266 broadcast: None,
5267 prefixlen: 24,
5268 })
5269 }
5270
5271 fn test_ifaddr_v6(ip: Ipv6Addr) -> IfAddr {
5272 IfAddr::V6(Ifv6Addr {
5273 ip,
5274 netmask: Ipv6Addr::from(u128::MAX << 64),
5275 broadcast: None,
5276 prefixlen: 64,
5277 })
5278 }
5279
5280 #[test]
5281 fn test_resolve_max_packet_size() {
5282 let interfaces = vec![
5284 test_interface("en0", 1, test_ifaddr_v4(Ipv4Addr::new(192, 168, 1, 2))),
5285 test_interface(
5286 "en0",
5287 1,
5288 test_ifaddr_v6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)),
5289 ),
5290 test_interface("en1", 2, test_ifaddr_v4(Ipv4Addr::new(10, 0, 0, 2))),
5291 ];
5292
5293 let resolve = |selections: &[MaxPacketSizeSelection], if_index, is_ipv4| {
5294 resolve_max_packet_size(selections, &interfaces, if_index, is_ipv4)
5295 };
5296
5297 assert_eq!(resolve(&[], 1, true), MAX_PKT_DEFAULT);
5299 assert_eq!(resolve(&[], 1, false), MAX_PKT_DEFAULT);
5300
5301 let by_name = vec![MaxPacketSizeSelection {
5303 if_kind: IfKind::Name("en0".to_string()),
5304 max_packet_size: 8000,
5305 }];
5306 assert_eq!(resolve(&by_name, 1, true), 8000);
5307 assert_eq!(resolve(&by_name, 1, false), 8000);
5308 assert_eq!(resolve(&by_name, 2, true), MAX_PKT_DEFAULT);
5309
5310 let overlapping = vec![
5312 MaxPacketSizeSelection {
5313 if_kind: IfKind::All,
5314 max_packet_size: 8000,
5315 },
5316 MaxPacketSizeSelection {
5317 if_kind: IfKind::Name("en1".to_string()),
5318 max_packet_size: 4000,
5319 },
5320 ];
5321 assert_eq!(resolve(&overlapping, 1, true), 8000);
5322 assert_eq!(resolve(&overlapping, 1, false), 8000);
5323 assert_eq!(resolve(&overlapping, 2, true), 4000);
5324
5325 let v4_only = vec![MaxPacketSizeSelection {
5327 if_kind: IfKind::IPv4,
5328 max_packet_size: 8000,
5329 }];
5330 assert_eq!(resolve(&v4_only, 1, true), 8000);
5331 assert_eq!(resolve(&v4_only, 1, false), MAX_PKT_DEFAULT);
5332
5333 let v6_only = vec![MaxPacketSizeSelection {
5334 if_kind: IfKind::IPv6,
5335 max_packet_size: 8000,
5336 }];
5337 assert_eq!(resolve(&v6_only, 1, false), 8000);
5338 assert_eq!(resolve(&v6_only, 1, true), MAX_PKT_DEFAULT);
5339 assert_eq!(resolve(&v6_only, 2, true), MAX_PKT_DEFAULT);
5341 assert_eq!(resolve(&v6_only, 2, false), MAX_PKT_DEFAULT);
5342
5343 let by_index_v4 = vec![MaxPacketSizeSelection {
5345 if_kind: IfKind::IndexV4(1),
5346 max_packet_size: 8000,
5347 }];
5348 assert_eq!(resolve(&by_index_v4, 1, true), 8000);
5349 assert_eq!(resolve(&by_index_v4, 1, false), MAX_PKT_DEFAULT);
5350 }
5351
5352 #[test]
5355 fn test_set_max_packet_size_range() {
5356 let daemon = ServiceDaemon::new().unwrap();
5357
5358 assert!(daemon
5359 .set_max_packet_size(IfKind::All, MIN_MAX_PACKET_SIZE - 1)
5360 .is_err());
5361 assert!(daemon
5362 .set_max_packet_size(IfKind::All, MAX_PKT_ABSOLUTE_IPV6 + 1)
5363 .is_err());
5364
5365 assert!(daemon
5367 .set_max_packet_size(IfKind::All, MIN_MAX_PACKET_SIZE)
5368 .is_ok());
5369 assert!(daemon
5370 .set_max_packet_size(IfKind::All, MAX_PKT_ABSOLUTE_IPV6)
5371 .is_ok());
5372
5373 daemon.shutdown().unwrap();
5374 }
5375
5376 #[test]
5377 fn test_response_source_ifaddr_match() {
5378 let ifaddr_a = IfAddr::V4(Ifv4Addr {
5382 ip: Ipv4Addr::new(192, 168, 1, 148),
5383 netmask: Ipv4Addr::new(255, 255, 255, 0),
5384 broadcast: None,
5385 prefixlen: 24,
5386 });
5387 let ifaddr_b = IfAddr::V4(Ifv4Addr {
5388 ip: Ipv4Addr::new(10, 238, 0, 51),
5389 netmask: Ipv4Addr::new(255, 255, 255, 0),
5390 broadcast: None,
5391 prefixlen: 24,
5392 });
5393
5394 let intf = MyIntf {
5395 name: "dummy0".to_string(),
5396 index: 1,
5397 addrs: HashSet::from([ifaddr_a.clone(), ifaddr_b.clone()]),
5398 max_packet_size_v4: MAX_PKT_DEFAULT,
5399 max_packet_size_v6: MAX_PKT_DEFAULT,
5400 };
5401
5402 let pick = |querier: IpAddr| -> Option<IfAddr> {
5403 intf.addrs
5404 .iter()
5405 .find(|a| valid_ip_on_intf(&querier, a))
5406 .cloned()
5407 };
5408
5409 assert_eq!(
5410 pick(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 2))),
5411 Some(ifaddr_a)
5412 );
5413 assert_eq!(
5414 pick(IpAddr::V4(Ipv4Addr::new(10, 238, 0, 99))),
5415 Some(ifaddr_b)
5416 );
5417 assert_eq!(pick(IpAddr::V4(Ipv4Addr::new(172, 16, 0, 1))), None);
5419 }
5420
5421 #[test]
5422 fn test_instance_name() {
5423 assert!(valid_instance_name("my-laser._printer._tcp.local."));
5424 assert!(valid_instance_name("my-laser.._printer._tcp.local."));
5425 assert!(!valid_instance_name("_printer._tcp.local."));
5426 }
5427
5428 #[test]
5429 fn test_legacy_unicast_response() {
5430 let intf_ip = match my_ip_interfaces(false)
5441 .into_iter()
5442 .find_map(|intf| match intf.ip() {
5443 IpAddr::V4(ip) => Some(ip),
5444 IpAddr::V6(_) => None,
5445 }) {
5446 Some(ip) => ip,
5447 None => {
5448 println!("No IPv4 interface available; skipping test.");
5449 return;
5450 }
5451 };
5452
5453 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5455 let unique = SystemTime::now()
5456 .duration_since(SystemTime::UNIX_EPOCH)
5457 .unwrap()
5458 .as_micros();
5459 let hostname = format!("legacy-unicast-test-{unique}.local.");
5460 let service_info = ServiceInfo::new(
5461 "_legacy-uni._udp.local.",
5462 "test_instance",
5463 &hostname,
5464 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5465 5353, None,
5467 )
5468 .expect("invalid service info");
5469 daemon.register(service_info).expect("register service");
5470
5471 let querier = UdpSocket::bind((intf_ip, 0)).expect("bind querier socket");
5475 querier
5476 .set_multicast_loop_v4(true)
5477 .expect("enable multicast loopback");
5478 querier
5479 .set_read_timeout(Some(Duration::from_millis(500)))
5480 .expect("set read timeout");
5481 assert_ne!(
5482 querier.local_addr().unwrap().port(),
5483 MDNS_PORT,
5484 "querier must use an ephemeral (non-5353) source port"
5485 );
5486
5487 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5489 query.add_question(&hostname, RRType::A);
5490 let query_packet = query
5491 .to_data_on_wire(MAX_PKT_DEFAULT, true)
5492 .pop()
5493 .expect("query serialized to one packet");
5494
5495 let if_id = InterfaceId {
5496 name: "test".to_string(),
5497 index: 0,
5498 };
5499
5500 let deadline = Instant::now() + Duration::from_secs(8);
5503 let mut response = None;
5504 'outer: while Instant::now() < deadline {
5505 querier
5506 .send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5507 .expect("send query");
5508
5509 let mut buf = [0u8; 1500];
5512 while let Ok((len, from)) = querier.recv_from(&mut buf) {
5513 let Ok(msg) = DnsIncoming::new(buf[..len].to_vec(), if_id.clone()) else {
5514 continue;
5515 };
5516 if msg.is_response()
5517 && msg
5518 .answers()
5519 .iter()
5520 .any(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5521 {
5522 response = Some((msg, from));
5523 break 'outer;
5524 }
5525 }
5526 }
5527
5528 let (msg, from) = response.expect(
5529 "expected a unicast response to the legacy query; \
5530 a multicast-only reply would never reach this un-joined socket",
5531 );
5532
5533 assert_eq!(
5535 from.port(),
5536 MDNS_PORT,
5537 "response should originate from the mDNS port"
5538 );
5539
5540 assert!(
5542 msg.questions()
5543 .iter()
5544 .any(|q| q.entry_name().eq_ignore_ascii_case(&hostname)),
5545 "legacy unicast response must echo the question section"
5546 );
5547
5548 let answer = msg
5551 .answers()
5552 .iter()
5553 .find(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5554 .expect("response contains an answer for our hostname");
5555 assert_eq!(
5556 answer.get_type(),
5557 RRType::A,
5558 "an A query should be answered with an A record"
5559 );
5560 assert!(
5561 !answer.get_cache_flush(),
5562 "legacy unicast responses must clear the cache-flush bit"
5563 );
5564
5565 daemon.shutdown().unwrap();
5566 }
5567
5568 #[test]
5569 fn test_shared_response_delay_bounds() {
5570 assert_eq!(SHARED_RESPONSE_DELAY_MIN_MILLIS, 10);
5575 assert_eq!(SHARED_RESPONSE_DELAY_MAX_MILLIS, 50);
5576 for _ in 0..10_000 {
5577 let d =
5578 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
5579 assert!(
5580 (SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS).contains(&d),
5581 "delay {} ms is outside the configured {}-{} ms range",
5582 d,
5583 SHARED_RESPONSE_DELAY_MIN_MILLIS,
5584 SHARED_RESPONSE_DELAY_MAX_MILLIS
5585 );
5586 }
5587 }
5588
5589 #[test]
5590 fn test_initial_query_delayed() {
5591 use socket2::{Domain, Protocol, Socket, Type};
5598
5599 let (intf, intf_ip) = match my_ip_interfaces(false)
5600 .into_iter()
5601 .find_map(|intf| match intf.ip() {
5602 IpAddr::V4(ip) if !ip.is_loopback() => Some((intf, ip)),
5603 _ => None,
5604 }) {
5605 Some(pair) => pair,
5606 None => {
5607 println!("No IPv4 interface available; skipping test.");
5608 return;
5609 }
5610 };
5611 let interface_id = InterfaceId::from(&intf);
5612
5613 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5617 sock.set_reuse_address(true).unwrap();
5618 #[cfg(unix)]
5619 sock.set_reuse_port(true).unwrap();
5620 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5621 .unwrap();
5622 sock.join_multicast_v4(&GROUP_ADDR_V4, &intf_ip).unwrap();
5623 sock.set_read_timeout(Some(Duration::from_millis(200)))
5624 .unwrap();
5625 let sock: UdpSocket = sock.into();
5626
5627 let unique = SystemTime::now()
5629 .duration_since(SystemTime::UNIX_EPOCH)
5630 .unwrap()
5631 .as_micros()
5632 % 1_000_000_000;
5633 let service_type = format!("_qd{unique}._udp.local.");
5634
5635 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5636
5637 let sent_at = Instant::now();
5638 let _browse = daemon.browse(&service_type).expect("browse");
5639
5640 let deadline = Instant::now() + Duration::from_secs(2);
5643 let mut buf = [0u8; 2048];
5644 let mut measured = None;
5645 while Instant::now() < deadline {
5646 let n = match sock.recv_from(&mut buf) {
5647 Ok((n, _)) => n,
5648 Err(_) => continue, };
5650 let Ok(msg) = DnsIncoming::new(buf[..n].to_vec(), interface_id.clone()) else {
5651 continue;
5652 };
5653 if msg.is_query()
5654 && msg
5655 .questions()
5656 .iter()
5657 .any(|q| q.entry_name() == service_type)
5658 {
5659 measured = Some(sent_at.elapsed());
5660 break;
5661 }
5662 }
5663
5664 daemon.shutdown().unwrap();
5665
5666 let elapsed = measured.expect("expected the daemon to send a PTR query for our browse");
5667 let tolerance = Duration::from_millis(2);
5668 assert!(
5669 elapsed + tolerance >= Duration::from_millis(INITIAL_QUERY_DELAY_MIN_MILLIS),
5670 "first browse query was sent after only {:?}; the first query of a series must be \
5671 delayed (10-50 ms window), not sent immediately",
5672 elapsed
5673 );
5674
5675 let scheduling_slack = Duration::from_millis(50);
5680 assert!(
5681 elapsed <= Duration::from_millis(INITIAL_QUERY_DELAY_MAX_MILLIS) + scheduling_slack,
5682 "first browse query was sent after {:?}, beyond the {}-{} ms jitter window (plus slack)",
5683 elapsed,
5684 INITIAL_QUERY_DELAY_MIN_MILLIS,
5685 INITIAL_QUERY_DELAY_MAX_MILLIS
5686 );
5687 }
5688
5689 #[test]
5690 fn test_shared_ptr_response_delayed() {
5691 use socket2::{Domain, Protocol, Socket, Type};
5698
5699 let intf_ip = match my_ip_interfaces(false)
5700 .into_iter()
5701 .find_map(|intf| match intf.ip() {
5702 IpAddr::V4(ip) if !ip.is_loopback() => Some(ip),
5703 _ => None,
5704 }) {
5705 Some(ip) => ip,
5706 None => {
5707 println!("No IPv4 interface available; skipping test.");
5708 return;
5709 }
5710 };
5711
5712 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5713 let monitor = daemon.monitor().expect("monitor daemon events");
5714
5715 let unique = SystemTime::now()
5718 .duration_since(SystemTime::UNIX_EPOCH)
5719 .unwrap()
5720 .as_micros()
5721 % 1_000_000_000;
5722 let service_type = format!("_sd{unique}._udp.local.");
5723 let hostname = format!("sd{unique}.local.");
5724 let service_info = ServiceInfo::new(
5725 &service_type,
5726 "test_instance",
5727 &hostname,
5728 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5729 5353,
5730 None,
5731 )
5732 .expect("invalid service info");
5733 daemon.register(service_info).expect("register service");
5734
5735 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5739 sock.set_reuse_address(true).unwrap();
5740 #[cfg(unix)]
5741 sock.set_reuse_port(true).unwrap();
5742 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5743 .unwrap();
5744 sock.set_multicast_if_v4(&intf_ip).unwrap();
5745 sock.set_multicast_loop_v4(true).unwrap();
5747 let sock: UdpSocket = sock.into();
5748
5749 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5751 query.add_question(&service_type, RRType::PTR);
5752 let query_packet = query
5753 .to_data_on_wire(MAX_PKT_DEFAULT, true)
5754 .pop()
5755 .expect("one packet");
5756
5757 std::thread::sleep(Duration::from_secs(3));
5761
5762 let deadline = Instant::now() + Duration::from_secs(8);
5766 let mut measured = None;
5767 while Instant::now() < deadline {
5768 while monitor.try_recv().is_ok() {}
5771
5772 let sent_at = Instant::now();
5773 sock.send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5774 .expect("send query");
5775
5776 let attempt_deadline = sent_at + Duration::from_millis(700);
5779 loop {
5780 let remaining = attempt_deadline.saturating_duration_since(Instant::now());
5781 if remaining.is_zero() {
5782 break;
5783 }
5784 match monitor.recv_timeout(remaining) {
5785 Ok(DaemonEvent::Respond(_)) => {
5786 measured = Some(sent_at.elapsed());
5787 break;
5788 }
5789 Ok(_) => continue, Err(_) => break, }
5792 }
5793 if measured.is_some() {
5794 break;
5795 }
5796 }
5797
5798 let elapsed =
5799 measured.expect("expected the daemon to respond to our PTR query within the deadline");
5800 assert!(
5801 elapsed >= Duration::from_millis(8),
5802 "PTR response was sent after only {:?}; a shared-record response must be \
5803 delayed (10-50 ms window), not sent immediately",
5804 elapsed
5805 );
5806 assert!(
5807 elapsed <= Duration::from_millis(600),
5808 "PTR response was sent after {:?}; expected within the 10-50 ms delay window",
5809 elapsed
5810 );
5811
5812 daemon.shutdown().unwrap();
5813 }
5814
5815 #[test]
5816 fn test_check_service_name_length() {
5817 let result = check_service_name_length("_tcp", 100);
5818 assert!(result.is_err());
5819 if let Err(e) = result {
5820 println!("{}", e);
5821 }
5822 }
5823
5824 #[test]
5825 fn test_check_hostname() {
5826 for hostname in &[
5828 "my_host.local.",
5829 &("A".repeat(255 - ".local.".len()) + ".local."),
5830 ] {
5831 let result = check_hostname(hostname);
5832 assert!(result.is_ok());
5833 }
5834
5835 for hostname in &[
5837 "my_host.local",
5838 ".local.",
5839 &("A".repeat(256 - ".local.".len()) + ".local."),
5840 ] {
5841 let result = check_hostname(hostname);
5842 assert!(result.is_err());
5843 if let Err(e) = result {
5844 println!("{}", e);
5845 }
5846 }
5847 }
5848
5849 #[test]
5850 fn test_check_domain_suffix() {
5851 assert!(check_domain_suffix("_missing_dot._tcp.local").is_err());
5852 assert!(check_domain_suffix("_missing_bar.tcp.local.").is_err());
5853 assert!(check_domain_suffix("_mis_spell._tpp.local.").is_err());
5854 assert!(check_domain_suffix("_mis_spell._upp.local.").is_err());
5855 assert!(check_domain_suffix("_has_dot._tcp.local.").is_ok());
5856 assert!(check_domain_suffix("_goodname._udp.local.").is_ok());
5857 }
5858
5859 #[test]
5860 fn test_service_with_temporarily_invalidated_ptr() {
5861 let d = ServiceDaemon::new().expect("Failed to create daemon");
5863
5864 let service = "_test_inval_ptr._udp.local.";
5865 let host_name = "my_host_tmp_invalidated_ptr.local.";
5866 let intfs: Vec<_> = my_ip_interfaces(false);
5867 let intf_ips: Vec<_> = intfs.iter().map(|intf| intf.ip()).collect();
5868 let port = 5201;
5869 let my_service =
5870 ServiceInfo::new(service, "my_instance", host_name, &intf_ips[..], port, None)
5871 .expect("invalid service info")
5872 .enable_addr_auto();
5873 let result = d.register(my_service.clone());
5874 assert!(result.is_ok());
5875
5876 let browse_chan = d.browse(service).unwrap();
5878 let timeout = Duration::from_secs(2);
5879 let mut resolved = false;
5880
5881 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5882 match event {
5883 ServiceEvent::ServiceResolved(info) => {
5884 resolved = true;
5885 println!("Resolved a service of {}", &info.fullname);
5886 break;
5887 }
5888 e => {
5889 println!("Received event {:?}", e);
5890 }
5891 }
5892 }
5893
5894 assert!(resolved);
5895
5896 println!("Stopping browse of {}", service);
5897 d.stop_browse(service).unwrap();
5900
5901 let mut stopped = false;
5906 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5907 match event {
5908 ServiceEvent::SearchStopped(_) => {
5909 stopped = true;
5910 println!("Stopped browsing service");
5911 break;
5912 }
5913 e => {
5917 println!("Received event {:?}", e);
5918 }
5919 }
5920 }
5921
5922 assert!(stopped);
5923
5924 let invalidate_ptr_packet = DnsPointer::new(
5926 my_service.get_type(),
5927 RRType::PTR,
5928 CLASS_IN,
5929 0,
5930 my_service.get_fullname().to_string(),
5931 );
5932
5933 let mut packet_buffer = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
5934 packet_buffer.add_additional_answer(invalidate_ptr_packet);
5935
5936 for intf in intfs {
5937 let sock = _new_socket_bind(&intf, true).unwrap();
5938 send_dns_outgoing_impl(
5939 &packet_buffer,
5940 &intf.name,
5941 intf.index.unwrap_or(0),
5942 &intf.addr,
5943 &sock.pktinfo,
5944 SendConfig {
5945 port: MDNS_PORT,
5946 max_packet_size: MAX_PKT_DEFAULT,
5947 is_ipv4: intf.addr.ip().is_ipv4(),
5948 },
5949 None,
5950 )
5951 .unwrap();
5952 }
5953
5954 println!(
5955 "Sent PTR record invalidation. Starting second browse for {}",
5956 service
5957 );
5958
5959 let browse_chan = d.browse(service).unwrap();
5961
5962 resolved = false;
5963 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5964 match event {
5965 ServiceEvent::ServiceResolved(info) => {
5966 resolved = true;
5967 println!("Resolved a service of {}", &info.fullname);
5968 break;
5969 }
5970 e => {
5971 println!("Received event {:?}", e);
5972 }
5973 }
5974 }
5975
5976 assert!(resolved);
5977 d.shutdown().unwrap();
5978 }
5979
5980 #[test]
5981 fn test_expired_srv() {
5982 let service_type = "_expired-srv._udp.local.";
5984 let instance = "test_instance";
5985 let host_name = "expired_srv_host.local.";
5986 let mut my_service = ServiceInfo::new(service_type, instance, host_name, "", 5023, None)
5987 .unwrap()
5988 .enable_addr_auto();
5989 let new_ttl = 3; my_service._set_host_ttl(new_ttl);
5994
5995 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
5997 let result = mdns_server.register(my_service);
5998 assert!(result.is_ok());
5999
6000 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6001 let browse_chan = mdns_client.browse(service_type).unwrap();
6002 let timeout = Duration::from_secs(2);
6003 let mut resolved = false;
6004
6005 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6006 if let ServiceEvent::ServiceResolved(info) = event {
6007 resolved = true;
6008 println!("Resolved a service of {}", &info.fullname);
6009 break;
6010 }
6011 }
6012
6013 assert!(resolved);
6014
6015 mdns_server.shutdown().unwrap();
6017
6018 let expire_timeout = Duration::from_secs(new_ttl as u64);
6020 while let Ok(event) = browse_chan.recv_timeout(expire_timeout) {
6021 if let ServiceEvent::ServiceRemoved(service_type, full_name) = event {
6022 println!("Service removed: {}: {}", &service_type, &full_name);
6023 break;
6024 }
6025 }
6026 }
6027
6028 #[test]
6029 fn test_hostname_resolution_address_removed() {
6030 let server = ServiceDaemon::new().expect("Failed to create server");
6032 let hostname = "addr_remove_host._tcp.local.";
6033 let service_ip_addr: ScopedIp = my_ip_interfaces(false)
6034 .iter()
6035 .find(|iface| iface.ip().is_ipv4())
6036 .map(|iface| iface.into())
6037 .unwrap();
6038
6039 let mut my_service = ServiceInfo::new(
6040 "_host_res_test._tcp.local.",
6041 "my_instance",
6042 hostname,
6043 service_ip_addr.to_ip_addr(),
6044 1234,
6045 None,
6046 )
6047 .expect("invalid service info");
6048
6049 let addr_ttl = 2;
6051 my_service._set_host_ttl(addr_ttl); server.register(my_service).unwrap();
6054
6055 let client = ServiceDaemon::new().expect("Failed to create client");
6057 let event_receiver = client.resolve_hostname(hostname, None).unwrap();
6058 let resolved = loop {
6059 match event_receiver.recv() {
6060 Ok(HostnameResolutionEvent::AddressesFound(found_hostname, addresses)) => {
6061 assert!(found_hostname == hostname);
6062 assert!(addresses.contains(&service_ip_addr));
6063 println!("address found: {:?}", &addresses);
6064 break true;
6065 }
6066 Ok(HostnameResolutionEvent::SearchStopped(_)) => break false,
6067 Ok(_event) => {}
6068 Err(_) => break false,
6069 }
6070 };
6071
6072 assert!(resolved);
6073
6074 server.shutdown().unwrap();
6076
6077 let timeout = Duration::from_secs(addr_ttl as u64 + 1);
6079 let removed = loop {
6080 match event_receiver.recv_timeout(timeout) {
6081 Ok(HostnameResolutionEvent::AddressesRemoved(removed_host, addresses)) => {
6082 assert!(removed_host == hostname);
6083 assert!(addresses.contains(&service_ip_addr));
6084
6085 println!(
6086 "address removed: hostname: {} addresses: {:?}",
6087 &hostname, &addresses
6088 );
6089 break true;
6090 }
6091 Ok(_event) => {}
6092 Err(_) => {
6093 break false;
6094 }
6095 }
6096 };
6097
6098 assert!(removed);
6099
6100 client.shutdown().unwrap();
6101 }
6102
6103 #[test]
6104 fn test_refresh_ptr() {
6105 let service_type = "_refresh-ptr._udp.local.";
6107 let instance = "test_instance";
6108 let host_name = "refresh_ptr_host.local.";
6109 let service_ip_addr = my_ip_interfaces(false)
6110 .iter()
6111 .find(|iface| iface.ip().is_ipv4())
6112 .map(|iface| iface.ip())
6113 .unwrap();
6114
6115 let mut my_service = ServiceInfo::new(
6116 service_type,
6117 instance,
6118 host_name,
6119 service_ip_addr,
6120 5023,
6121 None,
6122 )
6123 .unwrap();
6124
6125 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
6127
6128 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6130 let result = mdns_server.register(my_service);
6131 assert!(result.is_ok());
6132
6133 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6134 let browse_chan = mdns_client.browse(service_type).unwrap();
6135 let timeout = Duration::from_millis(1500); let mut resolved = false;
6137
6138 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6140 if let ServiceEvent::ServiceResolved(info) = event {
6141 resolved = true;
6142 println!("Resolved a service of {}", &info.fullname);
6143 break;
6144 }
6145 }
6146
6147 assert!(resolved);
6148
6149 let timeout = Duration::from_millis(new_ttl as u64 * 1000 * 90 / 100);
6151 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6152 println!("event: {:?}", &event);
6153 }
6154
6155 let metrics_chan = mdns_client.get_metrics().unwrap();
6157 let metrics = metrics_chan.recv_timeout(timeout).unwrap();
6158 let ptr_refresh_counter = metrics["cache-refresh-ptr"];
6159 assert_eq!(ptr_refresh_counter, 1);
6160 let srvtxt_refresh_counter = metrics["cache-refresh-srv-txt"];
6161 assert_eq!(srvtxt_refresh_counter, 1);
6162
6163 mdns_server.shutdown().unwrap();
6165 mdns_client.shutdown().unwrap();
6166 }
6167
6168 #[test]
6169 fn test_name_change() {
6170 assert_eq!(name_change("foo.local."), "foo (2).local.");
6171 assert_eq!(name_change("foo (2).local."), "foo (3).local.");
6172 assert_eq!(name_change("foo (9).local."), "foo (10).local.");
6173 assert_eq!(name_change("foo"), "foo (2)");
6174 assert_eq!(name_change("foo (2)"), "foo (3)");
6175 assert_eq!(name_change(""), " (2)");
6176
6177 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)"); }
6182
6183 #[test]
6184 fn test_hostname_change() {
6185 assert_eq!(hostname_change("foo.local."), "foo-2.local.");
6186 assert_eq!(hostname_change("foo"), "foo-2");
6187 assert_eq!(hostname_change("foo-2.local."), "foo-3.local.");
6188 assert_eq!(hostname_change("foo-9"), "foo-10");
6189 assert_eq!(hostname_change("test-42.domain."), "test-43.domain.");
6190 }
6191
6192 #[test]
6193 fn test_add_answer_txt_ttl() {
6194 let service_type = "_test_add_answer._udp.local.";
6196 let instance = "test_instance";
6197 let host_name = "add_answer_host.local.";
6198 let service_intf = my_ip_interfaces(false)
6199 .into_iter()
6200 .find(|iface| iface.ip().is_ipv4())
6201 .unwrap();
6202 let service_ip_addr = service_intf.ip();
6203 let my_service = ServiceInfo::new(
6204 service_type,
6205 instance,
6206 host_name,
6207 service_ip_addr,
6208 5023,
6209 None,
6210 )
6211 .unwrap();
6212
6213 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
6215
6216 let mut dummy_data = out.to_data_on_wire(MAX_PKT_DEFAULT, true);
6218 let interface_id = InterfaceId::from(&service_intf);
6219 let incoming = DnsIncoming::new(dummy_data.pop().unwrap(), interface_id).unwrap();
6220
6221 let if_addrs = vec![service_intf.ip()];
6223 add_answer_of_service(
6224 &mut out,
6225 &incoming,
6226 instance,
6227 &my_service,
6228 RRType::TXT,
6229 if_addrs,
6230 );
6231
6232 assert!(
6234 out.answers_count() > 0,
6235 "No answers added to the outgoing message"
6236 );
6237
6238 let answer = out._answers().first().unwrap();
6240 assert_eq!(answer.0.get_type(), RRType::TXT);
6241
6242 assert_eq!(answer.0.get_record().get_ttl(), my_service.get_other_ttl());
6244 }
6245
6246 #[test]
6247 fn test_interface_flip() {
6248 let ty_domain = "_intf-flip._udp.local.";
6250 let host_name = "intf_flip.local.";
6251 let now = SystemTime::now()
6252 .duration_since(SystemTime::UNIX_EPOCH)
6253 .unwrap();
6254 let instance_name = now.as_micros().to_string(); let port = 5200;
6256
6257 let (ip_addr1, intf_name) = my_ip_interfaces(false)
6259 .iter()
6260 .find(|iface| iface.ip().is_ipv4())
6261 .map(|iface| (iface.ip(), iface.name.clone()))
6262 .unwrap();
6263
6264 println!("Using interface {} with IP {}", intf_name, ip_addr1);
6265
6266 let service1 = ServiceInfo::new(ty_domain, &instance_name, host_name, ip_addr1, port, None)
6268 .expect("valid service info");
6269 let server1 = ServiceDaemon::new().expect("failed to start server");
6270 server1
6271 .register(service1)
6272 .expect("Failed to register service1");
6273
6274 std::thread::sleep(Duration::from_secs(2));
6276
6277 let client = ServiceDaemon::new().expect("failed to start client");
6279
6280 let receiver = client.browse(ty_domain).unwrap();
6281
6282 let timeout = Duration::from_secs(3);
6283 let mut got_data = false;
6284
6285 while let Ok(event) = receiver.recv_timeout(timeout) {
6286 if let ServiceEvent::ServiceResolved(_) = event {
6287 println!("Received ServiceResolved event");
6288 got_data = true;
6289 break;
6290 }
6291 }
6292
6293 assert!(got_data, "Should receive ServiceResolved event");
6294
6295 client.set_ip_check_interval(1).unwrap();
6297
6298 println!("Shutting down interface {}", &intf_name);
6300 client.test_down_interface(&intf_name).unwrap();
6301
6302 let mut got_removed = false;
6303
6304 while let Ok(event) = receiver.recv_timeout(timeout) {
6305 if let ServiceEvent::ServiceRemoved(ty_domain, instance) = event {
6306 got_removed = true;
6307 println!("removed: {ty_domain} : {instance}");
6308 break;
6309 }
6310 }
6311 assert!(got_removed, "Should receive ServiceRemoved event");
6312
6313 println!("Bringing up interface {}", &intf_name);
6314 client.test_up_interface(&intf_name).unwrap();
6315 let mut got_data = false;
6316 while let Ok(event) = receiver.recv_timeout(timeout) {
6317 if let ServiceEvent::ServiceResolved(resolved) = event {
6318 got_data = true;
6319 println!("Received ServiceResolved: {:?}", resolved);
6320 break;
6321 }
6322 }
6323 assert!(
6324 got_data,
6325 "Should receive ServiceResolved event after interface is back up"
6326 );
6327
6328 server1.shutdown().unwrap();
6329 client.shutdown().unwrap();
6330 }
6331
6332 #[test]
6333 fn test_cache_only() {
6334 let service_type = "_cache_only._udp.local.";
6336 let instance = "test_instance";
6337 let host_name = "cache_only_host.local.";
6338 let service_ip_addr = my_ip_interfaces(false)
6339 .iter()
6340 .find(|iface| iface.ip().is_ipv4())
6341 .map(|iface| iface.ip())
6342 .unwrap();
6343
6344 let mut my_service = ServiceInfo::new(
6345 service_type,
6346 instance,
6347 host_name,
6348 service_ip_addr,
6349 5023,
6350 None,
6351 )
6352 .unwrap();
6353
6354 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
6356
6357 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6358
6359 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6362 std::thread::sleep(Duration::from_secs(2));
6363
6364 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6366 let result = mdns_server.register(my_service);
6367 assert!(result.is_ok());
6368
6369 let timeout = Duration::from_millis(1500); let mut resolved = false;
6371
6372 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6374 if let ServiceEvent::ServiceResolved(info) = event {
6375 resolved = true;
6376 println!("Resolved a service of {}", &info.get_fullname());
6377 break;
6378 }
6379 }
6380
6381 assert!(resolved);
6382
6383 mdns_server.shutdown().unwrap();
6385 mdns_client.shutdown().unwrap();
6386 }
6387
6388 #[test]
6389 fn test_cache_only_unsolicited() {
6390 let service_type = "_c_unsolicit._udp.local.";
6391 let instance = "test_instance";
6392 let host_name = "c_unsolicit_host.local.";
6393 let service_ip_addr = my_ip_interfaces(false)
6394 .iter()
6395 .find(|iface| iface.ip().is_ipv4())
6396 .map(|iface| iface.ip())
6397 .unwrap();
6398
6399 let my_service = ServiceInfo::new(
6400 service_type,
6401 instance,
6402 host_name,
6403 service_ip_addr,
6404 5023,
6405 None,
6406 )
6407 .unwrap();
6408
6409 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6411 let result = mdns_server.register(my_service);
6412 assert!(result.is_ok());
6413
6414 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6415 mdns_client.accept_unsolicited(true).unwrap();
6416
6417 std::thread::sleep(Duration::from_secs(2));
6420 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6421 let timeout = Duration::from_millis(1500); let mut resolved = false;
6423
6424 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6426 if let ServiceEvent::ServiceResolved(info) = event {
6427 resolved = true;
6428 println!("Resolved a service of {}", &info.get_fullname());
6429 break;
6430 }
6431 }
6432
6433 assert!(resolved);
6434
6435 mdns_server.shutdown().unwrap();
6437 mdns_client.shutdown().unwrap();
6438 }
6439
6440 #[test]
6441 fn test_custom_port_isolation() {
6442 let service_type = "_custom_port._udp.local.";
6447 let instance_custom = "custom_port_instance";
6448 let instance_default = "default_port_instance";
6449 let host_name = "custom_port_host.local.";
6450
6451 let service_ip_addr = my_ip_interfaces(false)
6452 .iter()
6453 .find(|iface| iface.ip().is_ipv4())
6454 .map(|iface| iface.ip())
6455 .expect("Test requires an IPv4 interface");
6456
6457 let service_custom = ServiceInfo::new(
6459 service_type,
6460 instance_custom,
6461 host_name,
6462 service_ip_addr,
6463 8080,
6464 None,
6465 )
6466 .unwrap();
6467
6468 let service_default = ServiceInfo::new(
6470 service_type,
6471 instance_default,
6472 host_name,
6473 service_ip_addr,
6474 8081,
6475 None,
6476 )
6477 .unwrap();
6478
6479 let custom_port = 5454u16;
6481 let server_custom =
6482 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port server");
6483 let client_custom =
6484 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port client");
6485
6486 let server_default = ServiceDaemon::new().expect("Failed to create default port server");
6488
6489 server_custom
6491 .register(service_custom.clone())
6492 .expect("Failed to register custom port service");
6493
6494 server_default
6496 .register(service_default.clone())
6497 .expect("Failed to register default port service");
6498
6499 let browse_custom = client_custom
6501 .browse(service_type)
6502 .expect("Failed to browse on custom port");
6503
6504 let timeout = Duration::from_secs(3);
6505 let mut found_custom = false;
6506 let mut found_default_on_custom = false;
6507
6508 while let Ok(event) = browse_custom.recv_timeout(timeout) {
6510 if let ServiceEvent::ServiceResolved(info) = event {
6511 println!(
6512 "Custom port client resolved: {} on port {}",
6513 info.get_fullname(),
6514 info.get_port()
6515 );
6516 if info.get_fullname().starts_with(instance_custom) {
6517 found_custom = true;
6518 assert_eq!(info.get_port(), 8080);
6519 }
6520 if info.get_fullname().starts_with(instance_default) {
6521 found_default_on_custom = true;
6522 }
6523 }
6524 }
6525
6526 assert!(
6527 found_custom,
6528 "Custom port client should find service on custom port"
6529 );
6530 assert!(
6531 !found_default_on_custom,
6532 "Custom port client should NOT find service on default port"
6533 );
6534
6535 let client_default = ServiceDaemon::new().expect("Failed to create default port client");
6538 let browse_default = client_default
6539 .browse(service_type)
6540 .expect("Failed to browse on default port");
6541
6542 let mut found_default = false;
6543 let mut found_custom_on_default = false;
6544
6545 while let Ok(event) = browse_default.recv_timeout(timeout) {
6546 if let ServiceEvent::ServiceResolved(info) = event {
6547 println!(
6548 "Default port client resolved: {} on port {}",
6549 info.get_fullname(),
6550 info.get_port()
6551 );
6552 if info.get_fullname().starts_with(instance_default) {
6553 found_default = true;
6554 assert_eq!(info.get_port(), 8081);
6555 }
6556 if info.get_fullname().starts_with(instance_custom) {
6557 found_custom_on_default = true;
6558 }
6559 }
6560 }
6561
6562 assert!(
6563 found_default,
6564 "Default port client should find service on default port"
6565 );
6566 assert!(
6567 !found_custom_on_default,
6568 "Default port client should NOT find service on custom port"
6569 );
6570
6571 server_custom.shutdown().unwrap();
6573 client_custom.shutdown().unwrap();
6574 server_default.shutdown().unwrap();
6575 client_default.shutdown().unwrap();
6576 }
6577}