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 mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
2460 out.add_answer_at_time(
2461 DnsPointer::new(
2462 info.get_type(),
2463 RRType::PTR,
2464 CLASS_IN,
2465 0,
2466 info.get_fullname().to_string(),
2467 ),
2468 0,
2469 );
2470
2471 if let Some(sub) = info.get_subtype() {
2472 trace!("Adding subdomain {}", sub);
2473 out.add_answer_at_time(
2474 DnsPointer::new(
2475 sub,
2476 RRType::PTR,
2477 CLASS_IN,
2478 0,
2479 info.get_fullname().to_string(),
2480 ),
2481 0,
2482 );
2483 }
2484
2485 out.add_answer_at_time(
2486 DnsSrv::new(
2487 info.get_fullname(),
2488 CLASS_IN | CLASS_CACHE_FLUSH,
2489 0,
2490 info.get_priority(),
2491 info.get_weight(),
2492 info.get_port(),
2493 info.get_hostname().to_string(),
2494 ),
2495 0,
2496 );
2497 out.add_answer_at_time(
2498 DnsTxt::new(
2499 info.get_fullname(),
2500 CLASS_IN | CLASS_CACHE_FLUSH,
2501 0,
2502 info.generate_txt(),
2503 ),
2504 0,
2505 );
2506
2507 let if_addrs = if is_ipv4 {
2508 info.get_addrs_on_my_intf_v4(intf)
2509 } else {
2510 info.get_addrs_on_my_intf_v6(intf)
2511 };
2512
2513 if if_addrs.is_empty() {
2514 return vec![];
2515 }
2516
2517 for address in if_addrs {
2518 out.add_answer_at_time(
2519 DnsAddress::new(
2520 info.get_hostname(),
2521 ip_address_rr_type(&address),
2522 CLASS_IN | CLASS_CACHE_FLUSH,
2523 0,
2524 address,
2525 intf.into(),
2526 ),
2527 0,
2528 );
2529 }
2530
2531 let sent_vec = match send_dns_outgoing(&out, intf, sock, self.port, None, None) {
2533 Ok(sent_vec) => sent_vec,
2534 Err(InternalError::IntfAddrInvalid(intf_addr)) => {
2535 let invalid_intf_addrs = HashSet::from([intf_addr]);
2536 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2537 vec![]
2538 }
2539 };
2540 sent_vec.into_iter().next().unwrap_or_default()
2541 }
2542
2543 fn add_hostname_resolver(
2547 &mut self,
2548 hostname: String,
2549 listener: Sender<HostnameResolutionEvent>,
2550 timeout: Option<u64>,
2551 ) {
2552 let real_timeout = timeout.map(|t| current_time_millis() + t);
2553 self.hostname_resolvers
2554 .insert(hostname.to_lowercase(), (listener, real_timeout));
2555 if let Some(t) = real_timeout {
2556 self.add_timer(t);
2557 }
2558 }
2559
2560 fn send_query(&self, name: &str, qtype: RRType) {
2562 self.send_query_vec(&[(name, qtype)]);
2563 }
2564
2565 fn send_query_on_intf(&self, name: &str, qtype: RRType, intf: &MyIntf) {
2570 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2571 out.add_question(name, qtype);
2572
2573 let mut invalid_intf_addrs = HashSet::new();
2574 if let Some(sock) = self.ipv4_sock.as_ref() {
2575 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2576 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2577 {
2578 invalid_intf_addrs.insert(intf_addr);
2579 }
2580 }
2581 if let Some(sock) = self.ipv6_sock.as_ref() {
2582 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2583 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2584 {
2585 invalid_intf_addrs.insert(intf_addr);
2586 }
2587 }
2588 if !invalid_intf_addrs.is_empty() {
2589 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2590 }
2591 }
2592
2593 fn send_query_vec(&self, questions: &[(&str, RRType)]) {
2595 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
2596 let now = current_time_millis();
2597
2598 for (name, qtype) in questions {
2599 out.add_question(name, *qtype);
2600
2601 for record in self.cache.get_known_answers(name, *qtype, now) {
2602 trace!("add known answer: {:?}", record.record);
2610 let mut new_record = record.record.clone();
2611 new_record.get_record_mut().update_ttl(now);
2612 out.add_answer_box(new_record);
2613 }
2614 }
2615
2616 let mut invalid_intf_addrs = HashSet::new();
2617 for (_, intf) in self.my_intfs.iter() {
2618 if let Some(sock) = self.ipv4_sock.as_ref() {
2619 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2620 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2621 {
2622 invalid_intf_addrs.insert(intf_addr);
2623 }
2624 }
2625 if let Some(sock) = self.ipv6_sock.as_ref() {
2626 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
2627 send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None)
2628 {
2629 invalid_intf_addrs.insert(intf_addr);
2630 }
2631 }
2632 }
2633
2634 if !invalid_intf_addrs.is_empty() {
2635 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addrs));
2636 }
2637 }
2638
2639 fn handle_read(&mut self, event_key: usize) -> bool {
2644 let is_ipv4 = event_key == IPV4_SOCK_EVENT_KEY;
2645 let sock_opt = match event_key {
2646 IPV4_SOCK_EVENT_KEY => &mut self.ipv4_sock,
2647 IPV6_SOCK_EVENT_KEY => &mut self.ipv6_sock,
2648 _ => {
2649 debug!("handle_read: unknown token {}", event_key);
2650 return false;
2651 }
2652 };
2653 let Some(sock) = sock_opt.as_mut() else {
2654 debug!("handle_read: socket not available for token {}", event_key);
2655 return false;
2656 };
2657 let max_size = max_pkt_absolute(is_ipv4);
2661 let mut buf = vec![0u8; max_size + 1];
2662
2663 let (sz, pktinfo) = match sock.pktinfo.recv(&mut buf) {
2665 Ok(sz) => sz,
2666 Err(e) => {
2667 if e.kind() != std::io::ErrorKind::WouldBlock {
2668 debug!("listening socket read failed: {}", e);
2669 }
2670 return false;
2671 }
2672 };
2673
2674 if sz > max_size {
2683 debug!(
2684 "handle_read: dropping over-sized datagram of at least {} bytes (max {})",
2685 sz, max_size
2686 );
2687 return true; }
2689
2690 let pkt_if_index = pktinfo.if_index as u32;
2692 let Some(my_intf) = self.my_intfs.get(&pkt_if_index) else {
2693 debug!(
2694 "handle_read: no interface found for pktinfo if_index: {}",
2695 pktinfo.if_index
2696 );
2697 return true; };
2699
2700 let is_ipv4 = event_key == IPV4_SOCK_EVENT_KEY;
2705 if (is_ipv4 && my_intf.next_ifaddr_v4().is_none())
2706 || (!is_ipv4 && my_intf.next_ifaddr_v6().is_none())
2707 {
2708 debug!(
2709 "handle_read: dropping {} packet on intf {} (disabled)",
2710 if is_ipv4 { "IPv4" } else { "IPv6" },
2711 my_intf.name
2712 );
2713 return true;
2714 }
2715
2716 buf.truncate(sz); match DnsIncoming::new(buf, my_intf.into()) {
2719 Ok(msg) => {
2720 if msg.is_query() {
2721 let querier_addr = pktinfo.addr_src;
2722 self.handle_query(msg, pkt_if_index, querier_addr);
2723 } else if msg.is_response() {
2724 self.handle_response(msg, pkt_if_index);
2725 } else {
2726 debug!("Invalid message: not query and not response");
2727 }
2728 }
2729 Err(e) => debug!("Invalid incoming DNS message: {}", e),
2730 }
2731
2732 true
2733 }
2734
2735 fn query_unresolved(&mut self, instance: &str) -> bool {
2737 if !valid_instance_name(instance) {
2738 trace!("instance name {} not valid", instance);
2739 return false;
2740 }
2741
2742 if let Some(records) = self.cache.get_srv(instance) {
2743 for record in records {
2744 if let Some(srv) = record.record.any().downcast_ref::<DnsSrv>() {
2745 if self.cache.get_addr(srv.host()).is_none() {
2746 self.send_query_vec(&[(srv.host(), RRType::A), (srv.host(), RRType::AAAA)]);
2747 return true;
2748 }
2749 }
2750 }
2751 } else {
2752 self.send_query(instance, RRType::ANY);
2753 return true;
2754 }
2755
2756 false
2757 }
2758
2759 fn query_cache_for_service(
2762 &mut self,
2763 ty_domain: &str,
2764 sender: &Sender<ServiceEvent>,
2765 now: u64,
2766 ) {
2767 let mut resolved: HashSet<String> = HashSet::new();
2768 let mut unresolved: HashSet<String> = HashSet::new();
2769
2770 if let Some(records) = self.cache.get_ptr(ty_domain) {
2771 for record in records.iter().filter(|r| !r.record.expires_soon(now)) {
2772 if let Some(ptr) = record.record.any().downcast_ref::<DnsPointer>() {
2773 let mut new_event = None;
2774 match self.resolve_service_from_cache(ty_domain, ptr.alias()) {
2775 Ok(resolved_service) => {
2776 if resolved_service.is_valid() {
2777 debug!("Resolved service from cache: {}", ptr.alias());
2778 new_event =
2779 Some(ServiceEvent::ServiceResolved(Box::new(resolved_service)));
2780 } else {
2781 debug!("Resolved service is not valid: {}", ptr.alias());
2782 }
2783 }
2784 Err(err) => {
2785 debug!("Error while resolving service from cache: {}", err);
2786 continue;
2787 }
2788 }
2789
2790 match sender.send(ServiceEvent::ServiceFound(
2791 ty_domain.to_string(),
2792 ptr.alias().to_string(),
2793 )) {
2794 Ok(()) => debug!("sent service found {}", ptr.alias()),
2795 Err(e) => {
2796 debug!("failed to send service found: {}", e);
2797 continue;
2798 }
2799 }
2800
2801 if let Some(event) = new_event {
2802 resolved.insert(ptr.alias().to_string());
2803 match sender.send(event) {
2804 Ok(()) => debug!("sent service resolved: {}", ptr.alias()),
2805 Err(e) => debug!("failed to send service resolved: {}", e),
2806 }
2807 } else {
2808 unresolved.insert(ptr.alias().to_string());
2809 }
2810 }
2811 }
2812 }
2813
2814 for instance in resolved.drain() {
2815 self.pending_resolves.remove(&instance);
2816 self.resolved.insert(instance);
2817 }
2818
2819 for instance in unresolved.drain() {
2820 self.add_pending_resolve(instance);
2821 }
2822 }
2823
2824 fn query_cache_for_hostname(
2827 &mut self,
2828 hostname: &str,
2829 sender: Sender<HostnameResolutionEvent>,
2830 ) {
2831 let addresses_map = self.cache.get_addresses_for_host(hostname);
2832 for (name, addresses) in addresses_map {
2833 match sender.send(HostnameResolutionEvent::AddressesFound(name, addresses)) {
2834 Ok(()) => trace!("sent hostname addresses found"),
2835 Err(e) => debug!("failed to send hostname addresses found: {}", e),
2836 }
2837 }
2838 }
2839
2840 fn add_pending_resolve(&mut self, instance: String) {
2841 if !self.pending_resolves.contains(&instance) {
2842 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
2843 self.add_retransmission(next_time, Command::Resolve(instance.clone(), 1));
2844 self.pending_resolves.insert(instance);
2845 }
2846 }
2847
2848 fn resolve_service_from_cache(
2850 &self,
2851 ty_domain: &str,
2852 fullname: &str,
2853 ) -> Result<ResolvedService> {
2854 let now = current_time_millis();
2855 let mut resolved_service = ResolvedService {
2856 ty_domain: ty_domain.to_string(),
2857 sub_ty_domain: None,
2858 fullname: fullname.to_string(),
2859 host: String::new(),
2860 port: 0,
2861 addresses: HashSet::new(),
2862 txt_properties: TxtProperties::new(),
2863 };
2864
2865 if let Some(subtype) = self.cache.get_subtype(fullname) {
2867 trace!(
2868 "ty_domain: {} found subtype {} for instance: {}",
2869 ty_domain,
2870 subtype,
2871 fullname
2872 );
2873 if resolved_service.sub_ty_domain.is_none() {
2874 resolved_service.sub_ty_domain = Some(subtype.to_string());
2875 }
2876 }
2877
2878 if let Some(records) = self.cache.get_srv(fullname) {
2880 if let Some(answer) = records.iter().find(|r| !r.record.expires_soon(now)) {
2881 if let Some(dns_srv) = answer.record.any().downcast_ref::<DnsSrv>() {
2882 resolved_service.host = dns_srv.host().to_string();
2883 resolved_service.port = dns_srv.port();
2884 }
2885 }
2886 }
2887
2888 if let Some(records) = self.cache.get_txt(fullname) {
2890 if let Some(record) = records.iter().find(|r| !r.record.expires_soon(now)) {
2891 if let Some(dns_txt) = record.record.any().downcast_ref::<DnsTxt>() {
2892 resolved_service.txt_properties = dns_txt.text().into();
2893 }
2894 }
2895 }
2896
2897 if let Some(records) = self.cache.get_addr(&resolved_service.host) {
2899 for answer in records.iter() {
2900 if let Some(dns_a) = answer.record.any().downcast_ref::<DnsAddress>() {
2901 if dns_a.expires_soon(now) {
2902 trace!(
2903 "Addr expired or expires soon: {}",
2904 dns_a.address().to_ip_addr()
2905 );
2906 } else {
2907 let scoped = dns_a.address();
2908 if let ScopedIp::V4(v4) = &scoped {
2909 let existing = resolved_service
2912 .addresses
2913 .iter()
2914 .find(|a| a.to_ip_addr() == IpAddr::V4(*v4.addr()))
2915 .cloned();
2916 if let Some(mut existing) = existing {
2917 resolved_service.addresses.remove(&existing);
2918 if let ScopedIp::V4(existing_v4) = &mut existing {
2919 for id in v4.interface_ids() {
2920 existing_v4.add_interface_id(id.clone());
2921 }
2922 }
2923 resolved_service.addresses.insert(existing);
2924 } else {
2925 resolved_service.addresses.insert(scoped);
2926 }
2927 } else {
2928 resolved_service.addresses.insert(scoped);
2929 }
2930 }
2931 }
2932 }
2933 }
2934
2935 Ok(resolved_service)
2936 }
2937
2938 fn handle_poller_events(&mut self, events: &mio::Events) {
2939 for ev in events.iter() {
2940 trace!("event received with key {:?}", ev.token());
2941 if ev.token().0 == SIGNAL_SOCK_EVENT_KEY {
2942 self.signal_sock_drain();
2944
2945 if let Err(e) = self.poller.registry().reregister(
2946 &mut self.signal_sock,
2947 ev.token(),
2948 mio::Interest::READABLE,
2949 ) {
2950 debug!("failed to modify poller for signal socket: {}", e);
2951 }
2952 continue; }
2954
2955 while self.handle_read(ev.token().0) {}
2957
2958 if ev.token().0 == IPV4_SOCK_EVENT_KEY {
2960 if let Some(sock) = self.ipv4_sock.as_mut() {
2962 if let Err(e) =
2963 self.poller
2964 .registry()
2965 .reregister(sock, ev.token(), mio::Interest::READABLE)
2966 {
2967 debug!("modify poller for IPv4 socket: {}", e);
2968 }
2969 }
2970 } else if ev.token().0 == IPV6_SOCK_EVENT_KEY {
2971 if let Some(sock) = self.ipv6_sock.as_mut() {
2973 if let Err(e) =
2974 self.poller
2975 .registry()
2976 .reregister(sock, ev.token(), mio::Interest::READABLE)
2977 {
2978 debug!("modify poller for IPv6 socket: {}", e);
2979 }
2980 }
2981 }
2982 }
2983 }
2984
2985 fn handle_response(&mut self, mut msg: DnsIncoming, if_index: u32) {
2988 let now = current_time_millis();
2989
2990 let mut record_predicate = |record: &DnsRecordBox| {
2992 if !record.get_record().is_expired(now) {
2993 return true;
2994 }
2995
2996 debug!("record is expired, removing it from cache.");
2997 if self.cache.remove(record) {
2998 if let Some(dns_ptr) = record.any().downcast_ref::<DnsPointer>() {
3000 call_service_listener(
3001 &self.service_queriers,
3002 dns_ptr.get_name(),
3003 ServiceEvent::ServiceRemoved(
3004 dns_ptr.get_name().to_string(),
3005 dns_ptr.alias().to_string(),
3006 ),
3007 );
3008 }
3009 }
3010 false
3011 };
3012 msg.answers_mut().retain(&mut record_predicate);
3013 msg.authorities_mut().retain(&mut record_predicate);
3014 msg.additionals_mut().retain(&mut record_predicate);
3015
3016 self.conflict_handler(&msg, if_index);
3018
3019 let mut is_for_us = true; for answer in msg.answers() {
3026 if answer.get_type() == RRType::PTR {
3027 if self.service_queriers.contains_key(answer.get_name()) {
3028 is_for_us = true;
3029 break; } else {
3031 is_for_us = false;
3032 }
3033 } else if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
3034 let answer_lowercase = answer.get_name().to_lowercase();
3036 if self.hostname_resolvers.contains_key(&answer_lowercase) {
3037 is_for_us = true;
3038 break; }
3040 }
3041 }
3042
3043 if self.accept_unsolicited {
3045 is_for_us = true;
3046 }
3047
3048 struct InstanceChange {
3050 ty: RRType, name: String, }
3053
3054 let mut changes = Vec::new();
3062 let mut timers = Vec::new();
3063 let Some(my_intf) = self.my_intfs.get(&if_index) else {
3064 return;
3065 };
3066 for record in msg.all_records() {
3067 match self
3068 .cache
3069 .add_or_update(my_intf, record, &mut timers, is_for_us)
3070 {
3071 Some((dns_record, true)) => {
3072 timers.push(dns_record.record.get_record().get_expire_time());
3073 timers.push(dns_record.record.get_record().get_refresh_time());
3074
3075 let ty = dns_record.record.get_type();
3076 let name = dns_record.record.get_name();
3077
3078 if ty == RRType::PTR && dns_record.record.get_record().get_ttl() > 1 {
3080 if self.service_queriers.contains_key(name) {
3081 timers.push(dns_record.record.get_record().get_refresh_time());
3082 }
3083
3084 if let Some(dns_ptr) = dns_record.record.any().downcast_ref::<DnsPointer>()
3086 {
3087 debug!("calling listener with service found: {name}");
3088 call_service_listener(
3089 &self.service_queriers,
3090 name,
3091 ServiceEvent::ServiceFound(
3092 name.to_string(),
3093 dns_ptr.alias().to_string(),
3094 ),
3095 );
3096 changes.push(InstanceChange {
3097 ty,
3098 name: dns_ptr.alias().to_string(),
3099 });
3100 }
3101 } else {
3102 changes.push(InstanceChange {
3103 ty,
3104 name: name.to_string(),
3105 });
3106 }
3107 }
3108 Some((dns_record, false)) => {
3109 timers.push(dns_record.record.get_record().get_expire_time());
3110 timers.push(dns_record.record.get_record().get_refresh_time());
3111 }
3112 _ => {}
3113 }
3114 }
3115
3116 for t in timers {
3118 self.add_timer(t);
3119 }
3120
3121 for change in changes
3123 .iter()
3124 .filter(|change| change.ty == RRType::A || change.ty == RRType::AAAA)
3125 {
3126 let addr_map = self.cache.get_addresses_for_host(&change.name);
3127 for (name, addresses) in addr_map {
3128 call_hostname_resolution_listener(
3129 &self.hostname_resolvers,
3130 &change.name,
3131 HostnameResolutionEvent::AddressesFound(name, addresses),
3132 )
3133 }
3134 }
3135
3136 let mut updated_instances = HashSet::new();
3138 for update in changes {
3139 match update.ty {
3140 RRType::PTR | RRType::SRV | RRType::TXT => {
3141 updated_instances.insert(update.name);
3142 }
3143 RRType::A | RRType::AAAA => {
3144 let instances = self.cache.get_instances_on_host(&update.name);
3145 updated_instances.extend(instances);
3146 }
3147 _ => {}
3148 }
3149 }
3150
3151 self.resolve_updated_instances(&updated_instances);
3152 }
3153
3154 fn conflict_handler(&mut self, msg: &DnsIncoming, if_index: u32) {
3155 let Some(my_intf) = self.my_intfs.get(&if_index) else {
3156 debug!("handle_response: no intf found for index {if_index}");
3157 return;
3158 };
3159
3160 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3161 return;
3162 };
3163
3164 for answer in msg.answers().iter() {
3165 let mut new_records = Vec::new();
3166
3167 let name = answer.get_name();
3168 let Some(probe) = dns_registry.probing.get_mut(name) else {
3169 continue;
3170 };
3171
3172 if answer.get_type() == RRType::A || answer.get_type() == RRType::AAAA {
3174 if let Some(answer_addr) = answer.any().downcast_ref::<DnsAddress>() {
3175 if answer_addr.interface_id.index != if_index {
3176 debug!(
3177 "conflict handler: answer addr {:?} not in the subnet of intf {}",
3178 answer_addr, my_intf.name
3179 );
3180 continue;
3181 }
3182 }
3183
3184 let any_match = probe.records.iter().any(|r| {
3187 r.get_type() == answer.get_type()
3188 && r.get_class() == answer.get_class()
3189 && r.rrdata_match(answer.as_ref())
3190 });
3191 if any_match {
3192 continue; }
3194 }
3195
3196 probe.records.retain(|record| {
3197 if record.get_type() == answer.get_type()
3198 && record.get_class() == answer.get_class()
3199 && !record.rrdata_match(answer.as_ref())
3200 {
3201 debug!(
3202 "found conflict name: '{name}' record: {}: {} PEER: {}",
3203 record.get_type(),
3204 record.rdata_print(),
3205 answer.rdata_print()
3206 );
3207
3208 let mut new_record = record.clone();
3211 let new_name = match record.get_type() {
3212 RRType::A => hostname_change(name),
3213 RRType::AAAA => hostname_change(name),
3214 _ => name_change(name),
3215 };
3216 new_record.get_record_mut().set_new_name(new_name);
3217 new_records.push(new_record);
3218 return false; }
3220
3221 true
3222 });
3223
3224 let create_time = current_time_millis() + fastrand::u64(0..250);
3231
3232 let waiting_services = probe.waiting_services.clone();
3233
3234 for record in new_records {
3235 if dns_registry.update_hostname(name, record.get_name(), create_time) {
3236 self.timers.push(Reverse(create_time));
3237 }
3238
3239 dns_registry.name_changes.insert(
3241 record.get_record().get_original_name().to_string(),
3242 record.get_name().to_string(),
3243 );
3244
3245 let new_probe = match dns_registry.probing.get_mut(record.get_name()) {
3246 Some(p) => p,
3247 None => {
3248 let new_probe = dns_registry
3249 .probing
3250 .entry(record.get_name().to_string())
3251 .or_insert_with(|| {
3252 debug!("conflict handler: new probe of {}", record.get_name());
3253 Probe::new(create_time)
3254 });
3255 self.timers.push(Reverse(new_probe.next_send));
3256 new_probe
3257 }
3258 };
3259
3260 debug!(
3261 "insert record with new name '{}' {} into probe",
3262 record.get_name(),
3263 record.get_type()
3264 );
3265 new_probe.insert_record(record);
3266
3267 new_probe.waiting_services.extend(waiting_services.clone());
3268 }
3269 }
3270 }
3271
3272 fn resolve_updated_instances(&mut self, updated_instances: &HashSet<String>) {
3279 if updated_instances.is_empty() {
3280 return;
3281 }
3282
3283 let mut resolved: HashSet<String> = HashSet::new();
3284 let mut unresolved: HashSet<String> = HashSet::new();
3285 let mut removed_instances = HashMap::new();
3286
3287 let now = current_time_millis();
3288
3289 for (ty_domain, records) in self.cache.all_ptr().iter() {
3290 if !self.service_queriers.contains_key(ty_domain) {
3291 continue;
3293 }
3294
3295 for ptr in records.iter().filter(|r| !r.record.expires_soon(now)) {
3296 let Some(dns_ptr) = ptr.record.any().downcast_ref::<DnsPointer>() else {
3297 continue;
3298 };
3299
3300 let instance = dns_ptr.alias();
3301 if !updated_instances.contains(instance) {
3302 continue;
3303 }
3304
3305 let Ok(resolved_service) = self.resolve_service_from_cache(ty_domain, instance)
3306 else {
3307 continue;
3308 };
3309
3310 debug!("resolve_updated_instances: from cache: {instance}");
3311 if resolved_service.is_valid() {
3312 debug!("call queriers to resolve {instance}");
3313 resolved.insert(instance.to_string());
3314 let event = ServiceEvent::ServiceResolved(Box::new(resolved_service));
3315 call_service_listener(&self.service_queriers, ty_domain, event);
3316 } else {
3317 debug!("Resolved service is not valid: {instance}");
3318 if self.resolved.remove(dns_ptr.alias()) {
3319 removed_instances
3320 .entry(ty_domain.to_string())
3321 .or_insert_with(HashSet::new)
3322 .insert(instance.to_string());
3323 }
3324 unresolved.insert(instance.to_string());
3325 }
3326 }
3327 }
3328
3329 for instance in resolved.drain() {
3330 self.pending_resolves.remove(&instance);
3331 self.resolved.insert(instance);
3332 }
3333
3334 for instance in unresolved.drain() {
3335 self.add_pending_resolve(instance);
3336 }
3337
3338 if !removed_instances.is_empty() {
3339 debug!(
3340 "resolve_updated_instances: removed {}",
3341 &removed_instances.len()
3342 );
3343 self.notify_service_removal(removed_instances);
3344 }
3345 }
3346
3347 fn handle_query(&mut self, msg: DnsIncoming, if_index: u32, querier_addr: SocketAddr) {
3349 let querier_ip = querier_addr.ip();
3350 let is_ipv4 = querier_ip.is_ipv4();
3351 let sock_opt = if is_ipv4 {
3352 &self.ipv4_sock
3353 } else {
3354 &self.ipv6_sock
3355 };
3356 let Some(sock) = sock_opt.as_ref() else {
3357 debug!("handle_query: socket not available for intf {}", if_index);
3358 return;
3359 };
3360
3361 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
3362 let mut delayed = false;
3363
3364 const META_QUERY: &str = "_services._dns-sd._udp.local.";
3367
3368 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
3369 debug!("missing dns registry for intf {}", if_index);
3370 return;
3371 };
3372
3373 let Some(intf) = self.my_intfs.get(&if_index) else {
3374 debug!("handle_query: no intf found for index {if_index}");
3375 return;
3376 };
3377
3378 for question in msg.questions().iter() {
3379 let qtype = question.entry_type();
3380 let q_name = question.entry_name();
3381
3382 if qtype == RRType::PTR {
3383 if querier_addr.port() == MDNS_PORT && msg.num_authorities() == 0 {
3387 delayed = true;
3388 }
3389 for service in self.my_services.values() {
3390 if service.get_status(if_index) != ServiceStatus::Announced {
3391 continue;
3392 }
3393
3394 if service.matches_type_or_subtype(q_name) {
3395 out.add_answer_with_additionals(&msg, service, intf, dns_registry, is_ipv4);
3396 } else if q_name == META_QUERY {
3397 let ttl = service.get_other_ttl();
3398 let alias = service.get_type().to_string();
3399 let ptr = DnsPointer::new(q_name, RRType::PTR, CLASS_IN, ttl, alias);
3400 if !out.add_answer(&msg, ptr) {
3401 trace!("answer was not added for meta-query {:?}", &question);
3402 }
3403 }
3404 }
3405 } else {
3406 if qtype == RRType::ANY && msg.num_authorities() > 0 {
3408 if let Some(probe) = dns_registry.probing.get_mut(q_name) {
3409 probe.tiebreaking(&msg, q_name);
3410 }
3411 }
3412
3413 if qtype == RRType::A || qtype == RRType::AAAA || qtype == RRType::ANY {
3414 for service in self.my_services.values() {
3415 if service.get_status(if_index) != ServiceStatus::Announced {
3416 continue;
3417 }
3418
3419 let service_hostname = dns_registry.resolve_name(service.get_hostname());
3420
3421 if service_hostname.to_lowercase() == question.entry_name().to_lowercase() {
3422 let mut intf_addrs: Vec<IpAddr> = Vec::new();
3429 if qtype == RRType::A || qtype == RRType::ANY {
3430 intf_addrs.extend(service.get_addrs_on_my_intf_v4(intf));
3431 }
3432 if qtype == RRType::AAAA || qtype == RRType::ANY {
3433 intf_addrs.extend(service.get_addrs_on_my_intf_v6(intf));
3434 }
3435 if intf_addrs.is_empty()
3436 && (qtype == RRType::A || qtype == RRType::AAAA)
3437 {
3438 let t = match qtype {
3439 RRType::A => "TYPE_A",
3440 RRType::AAAA => "TYPE_AAAA",
3441 _ => "invalid_type",
3442 };
3443 trace!(
3444 "Cannot find valid addrs for {} response on intf {:?}",
3445 t,
3446 &intf
3447 );
3448 continue;
3449 }
3450 for address in intf_addrs {
3451 out.add_answer(
3452 &msg,
3453 DnsAddress::new(
3454 service_hostname,
3455 ip_address_rr_type(&address),
3456 CLASS_IN | CLASS_CACHE_FLUSH,
3457 service.get_host_ttl(),
3458 address,
3459 intf.into(),
3460 ),
3461 );
3462 }
3463 }
3464 }
3465 }
3466
3467 let query_name = q_name.to_lowercase();
3468 let service_opt = self
3469 .my_services
3470 .iter()
3471 .find(|(k, _v)| dns_registry.resolve_name(k.as_str()) == query_name)
3472 .map(|(_, v)| v);
3473
3474 let Some(service) = service_opt else {
3475 continue;
3476 };
3477
3478 if service.get_status(if_index) != ServiceStatus::Announced {
3479 continue;
3480 }
3481
3482 let intf_addrs = if is_ipv4 {
3483 service.get_addrs_on_my_intf_v4(intf)
3484 } else {
3485 service.get_addrs_on_my_intf_v6(intf)
3486 };
3487 if intf_addrs.is_empty() {
3488 debug!(
3489 "Cannot find valid addrs for TYPE_SRV response on intf {:?}",
3490 &intf
3491 );
3492 continue;
3493 }
3494
3495 add_answer_of_service(
3496 &mut out,
3497 &msg,
3498 question.entry_name(),
3499 service,
3500 qtype,
3501 intf_addrs,
3502 );
3503 }
3504 }
3505
3506 if delayed && out.answers_count() > 0 {
3508 out.set_id(msg.id());
3509 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3510 let delay =
3511 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
3512 let next_time = current_time_millis() + delay;
3513 self.delayed_responses.push(DelayedResponse {
3514 next_time,
3515 out,
3516 if_index,
3517 is_ipv4,
3518 });
3519 self.add_timer(next_time);
3520 return;
3521 }
3522
3523 if out.answers_count() > 0 {
3524 out.set_id(msg.id());
3525
3526 let matched_source = intf
3529 .addrs
3530 .iter()
3531 .find(|if_addr| valid_ip_on_intf(&querier_ip, if_addr));
3532
3533 let unicast_dest = if querier_addr.port() != MDNS_PORT {
3541 Some(querier_addr)
3542 } else {
3543 None
3544 };
3545
3546 if unicast_dest.is_some() {
3547 for q in msg.questions() {
3548 out.add_question(q.entry_name(), q.entry_type());
3549 }
3550 out.clear_cache_flush_bits();
3551 } else if msg.num_authorities() == 0 {
3552 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3559 }
3560
3561 if out.answers_count() > 0 {
3562 debug!("sending response on intf {}", &intf.name);
3563 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_dns_outgoing(
3564 &out,
3565 intf,
3566 &sock.pktinfo,
3567 self.port,
3568 matched_source,
3569 unicast_dest,
3570 ) {
3571 let invalid_intf_addr = HashSet::from([intf_addr]);
3572 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3573 }
3574
3575 let if_name = intf.name.clone();
3576
3577 self.increase_counter(Counter::Respond, 1);
3578 self.notify_monitors(DaemonEvent::Respond(if_name));
3579 }
3580 }
3581
3582 self.increase_counter(Counter::KnownAnswerSuppression, out.known_answer_count());
3583 }
3584
3585 fn send_delayed_response(&mut self, resp: DelayedResponse) {
3594 let DelayedResponse {
3595 mut out,
3596 if_index,
3597 is_ipv4,
3598 ..
3599 } = resp;
3600
3601 let sock_opt = if is_ipv4 {
3602 &self.ipv4_sock
3603 } else {
3604 &self.ipv6_sock
3605 };
3606 let Some(sock) = sock_opt.as_ref() else {
3607 debug!("send_delayed_response: socket not available for intf {if_index}");
3608 return;
3609 };
3610
3611 if let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) {
3612 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
3613 }
3614 if out.answers_count() == 0 {
3615 return;
3616 }
3617
3618 let Some(intf) = self.my_intfs.get(&if_index) else {
3619 debug!("send_delayed_response: no intf found for index {if_index}");
3620 return;
3621 };
3622
3623 let if_name = intf.name.clone();
3624 debug!("sending delayed response on intf {}", &if_name);
3625 let send_result = send_dns_outgoing(&out, intf, &sock.pktinfo, self.port, None, None);
3626
3627 if let Err(InternalError::IntfAddrInvalid(intf_addr)) = send_result {
3628 let invalid_intf_addr = HashSet::from([intf_addr]);
3629 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3630 }
3631
3632 self.increase_counter(Counter::Respond, 1);
3633 self.notify_monitors(DaemonEvent::Respond(if_name));
3634 }
3635
3636 fn increase_counter(&mut self, counter: Counter, count: i64) {
3638 let key = counter.to_string();
3639 match self.counters.get_mut(&key) {
3640 Some(v) => *v += count,
3641 None => {
3642 self.counters.insert(key, count);
3643 }
3644 }
3645 }
3646
3647 fn set_counter(&mut self, counter: Counter, count: i64) {
3649 let key = counter.to_string();
3650 self.counters.insert(key, count);
3651 }
3652
3653 fn signal_sock_drain(&self) {
3654 let mut signal_buf = [0; 1024];
3655
3656 while let Ok(sz) = self.signal_sock.recv(&mut signal_buf) {
3658 trace!(
3659 "signal socket recvd: {}",
3660 String::from_utf8_lossy(&signal_buf[0..sz])
3661 );
3662 }
3663 }
3664
3665 fn add_retransmission(&mut self, next_time: u64, command: Command) {
3666 self.retransmissions.push(ReRun { next_time, command });
3667 self.add_timer(next_time);
3668 }
3669
3670 fn notify_service_removal(&self, expired: HashMap<String, HashSet<String>>) {
3673 for (ty_domain, sender) in self.service_queriers.iter() {
3674 if let Some(instances) = expired.get(ty_domain) {
3675 for instance_name in instances {
3676 let event = ServiceEvent::ServiceRemoved(
3677 ty_domain.to_string(),
3678 instance_name.to_string(),
3679 );
3680 match sender.send(event) {
3681 Ok(()) => debug!("notify_service_removal: sent ServiceRemoved to listener of {ty_domain}: {instance_name}"),
3682 Err(e) => debug!("Failed to send event: {}", e),
3683 }
3684 }
3685 }
3686 }
3687 }
3688
3689 fn exec_command(&mut self, command: Command, repeating: bool) {
3693 trace!("exec_command: {:?} repeating: {}", &command, repeating);
3694 match command {
3695 Command::Browse(ty, next_delay, cache_only, listener) => {
3696 self.exec_command_browse(repeating, ty, next_delay, cache_only, listener);
3697 }
3698
3699 Command::ResolveHostname(hostname, next_delay, listener, timeout) => {
3700 self.exec_command_resolve_hostname(
3701 repeating, hostname, next_delay, listener, timeout,
3702 );
3703 }
3704
3705 Command::Register(service_info) => {
3706 self.register_service(*service_info);
3707 self.increase_counter(Counter::Register, 1);
3708 }
3709
3710 Command::RegisterResend(fullname, intf) => {
3711 trace!("register-resend service: {fullname} on {}", &intf);
3712 if let Err(InternalError::IntfAddrInvalid(intf_addr)) =
3713 self.exec_command_register_resend(fullname, intf)
3714 {
3715 let invalid_intf_addr = HashSet::from([intf_addr]);
3716 let _ = self.send_cmd_to_self(Command::InvalidIntfAddrs(invalid_intf_addr));
3717 }
3718 }
3719
3720 Command::Unregister(fullname, resp_s) => {
3721 trace!("unregister service {} repeat {}", &fullname, &repeating);
3722 self.exec_command_unregister(repeating, fullname, resp_s);
3723 }
3724
3725 Command::UnregisterResend(packet, if_index, is_ipv4) => {
3726 self.exec_command_unregister_resend(packet, if_index, is_ipv4);
3727 }
3728
3729 Command::StopBrowse(ty_domain) => self.exec_command_stop_browse(ty_domain),
3730
3731 Command::StopResolveHostname(hostname) => {
3732 self.exec_command_stop_resolve_hostname(hostname.to_lowercase())
3733 }
3734
3735 Command::Resolve(instance, try_count) => self.exec_command_resolve(instance, try_count),
3736
3737 Command::GetMetrics(resp_s) => self.exec_command_get_metrics(resp_s),
3738
3739 Command::GetStatus(resp_s) => match resp_s.send(self.status.clone()) {
3740 Ok(()) => trace!("Sent status to the client"),
3741 Err(e) => debug!("Failed to send status: {}", e),
3742 },
3743
3744 Command::Monitor(resp_s) => {
3745 self.monitors.push(resp_s);
3746 }
3747
3748 Command::SetOption(daemon_opt) => {
3749 self.process_set_option(daemon_opt);
3750 }
3751
3752 Command::GetOption(resp_s) => {
3753 let val = DaemonOptionVal {
3754 _service_name_len_max: self.service_name_len_max,
3755 ip_check_interval: self.ip_check_interval,
3756 };
3757 if let Err(e) = resp_s.send(val) {
3758 debug!("Failed to send options: {}", e);
3759 }
3760 }
3761
3762 Command::Verify(instance_fullname, timeout) => {
3763 self.exec_command_verify(instance_fullname, timeout, repeating);
3764 }
3765
3766 Command::InvalidIntfAddrs(invalid_intf_addrs) => {
3767 for intf_addr in invalid_intf_addrs {
3768 self.del_interface_addr(&intf_addr);
3769 }
3770
3771 self.check_ip_changes();
3772 }
3773
3774 _ => {
3775 debug!("unexpected command: {:?}", &command);
3776 }
3777 }
3778 }
3779
3780 fn exec_command_get_metrics(&mut self, resp_s: Sender<HashMap<String, i64>>) {
3781 self.set_counter(Counter::CachedPTR, self.cache.ptr_count() as i64);
3782 self.set_counter(Counter::CachedSRV, self.cache.srv_count() as i64);
3783 self.set_counter(Counter::CachedAddr, self.cache.addr_count() as i64);
3784 self.set_counter(Counter::CachedTxt, self.cache.txt_count() as i64);
3785 self.set_counter(Counter::CachedNSec, self.cache.nsec_count() as i64);
3786 self.set_counter(Counter::CachedSubtype, self.cache.subtype_count() as i64);
3787 self.set_counter(Counter::Timer, self.timers.len() as i64);
3788
3789 let dns_registry_probe_count: usize = self
3790 .dns_registry_map
3791 .values()
3792 .map(|r| r.probing.len())
3793 .sum();
3794 self.set_counter(Counter::DnsRegistryProbe, dns_registry_probe_count as i64);
3795
3796 let dns_registry_active_count: usize = self
3797 .dns_registry_map
3798 .values()
3799 .map(|r| r.active.values().map(|a| a.len()).sum::<usize>())
3800 .sum();
3801 self.set_counter(Counter::DnsRegistryActive, dns_registry_active_count as i64);
3802
3803 let dns_registry_timer_count: usize = self
3804 .dns_registry_map
3805 .values()
3806 .map(|r| r.new_timers.len())
3807 .sum();
3808 self.set_counter(Counter::DnsRegistryTimer, dns_registry_timer_count as i64);
3809
3810 let dns_registry_name_change_count: usize = self
3811 .dns_registry_map
3812 .values()
3813 .map(|r| r.name_changes.len())
3814 .sum();
3815 self.set_counter(
3816 Counter::DnsRegistryNameChange,
3817 dns_registry_name_change_count as i64,
3818 );
3819
3820 if let Err(e) = resp_s.send(self.counters.clone()) {
3822 debug!("Failed to send metrics: {}", e);
3823 }
3824 }
3825
3826 fn exec_command_browse(
3827 &mut self,
3828 repeating: bool,
3829 ty: String,
3830 next_delay: u32,
3831 cache_only: bool,
3832 listener: Sender<ServiceEvent>,
3833 ) {
3834 let pretty_addrs: Vec<String> = self
3835 .my_intfs
3836 .iter()
3837 .map(|(if_index, itf)| format!("{} ({if_index})", itf.name))
3838 .collect();
3839
3840 if let Err(e) = listener.send(ServiceEvent::SearchStarted(format!(
3841 "{ty} on {} interfaces [{}]",
3842 pretty_addrs.len(),
3843 pretty_addrs.join(", ")
3844 ))) {
3845 debug!(
3846 "Failed to send SearchStarted({})(repeating:{}): {}",
3847 &ty, repeating, e
3848 );
3849 return;
3850 }
3851
3852 let now = current_time_millis();
3853 if !repeating {
3854 self.service_queriers.insert(ty.clone(), listener.clone());
3858
3859 self.query_cache_for_service(&ty, &listener, now);
3861 }
3862
3863 if cache_only {
3864 match listener.send(ServiceEvent::SearchStopped(ty.clone())) {
3866 Ok(()) => debug!("SearchStopped sent for {}", &ty),
3867 Err(e) => debug!("Failed to send SearchStopped: {}", e),
3868 }
3869 return;
3870 }
3871
3872 if !repeating {
3873 let jitter =
3875 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3876 self.add_retransmission(now + jitter, Command::Browse(ty, 1, cache_only, listener));
3877 return;
3878 }
3879
3880 self.send_query(&ty, RRType::PTR);
3881 self.increase_counter(Counter::Browse, 1);
3882
3883 let next_time = now + (next_delay * 1000) as u64;
3884 let max_delay = 60 * 60;
3885 let delay = cmp::min(next_delay * 2, max_delay);
3886 self.add_retransmission(next_time, Command::Browse(ty, delay, cache_only, listener));
3887 }
3888
3889 fn exec_command_resolve_hostname(
3890 &mut self,
3891 repeating: bool,
3892 hostname: String,
3893 next_delay: u32,
3894 listener: Sender<HostnameResolutionEvent>,
3895 timeout: Option<u64>,
3896 ) {
3897 let addr_list: Vec<_> = self.my_intfs.iter().collect();
3898 if let Err(e) = listener.send(HostnameResolutionEvent::SearchStarted(format!(
3899 "{} on addrs {:?}",
3900 &hostname, &addr_list
3901 ))) {
3902 debug!(
3903 "Failed to send ResolveStarted({})(repeating:{}): {}",
3904 &hostname, repeating, e
3905 );
3906 return;
3907 }
3908 let now = current_time_millis();
3909 if !repeating {
3910 self.add_hostname_resolver(hostname.to_owned(), listener.clone(), timeout);
3911 self.query_cache_for_hostname(&hostname, listener.clone());
3913
3914 let jitter =
3916 fastrand::u64(INITIAL_QUERY_DELAY_MIN_MILLIS..INITIAL_QUERY_DELAY_MAX_MILLIS);
3917 self.add_retransmission(
3918 now + jitter,
3919 Command::ResolveHostname(hostname, 1, listener, None),
3920 );
3921 return;
3922 }
3923
3924 self.send_query_vec(&[(&hostname, RRType::A), (&hostname, RRType::AAAA)]);
3925 self.increase_counter(Counter::ResolveHostname, 1);
3926
3927 let next_time = now + u64::from(next_delay) * 1000;
3928 let max_delay = 60 * 60;
3929 let delay = cmp::min(next_delay * 2, max_delay);
3930
3931 if self
3933 .hostname_resolvers
3934 .get(&hostname)
3935 .and_then(|(_sender, timeout)| *timeout)
3936 .map(|timeout| next_time < timeout)
3937 .unwrap_or(true)
3938 {
3939 self.add_retransmission(
3940 next_time,
3941 Command::ResolveHostname(hostname, delay, listener, None),
3942 );
3943 }
3944 }
3945
3946 fn exec_command_resolve(&mut self, instance: String, try_count: u16) {
3947 let pending_query = self.query_unresolved(&instance);
3948 let max_try = 3;
3949 if pending_query && try_count < max_try {
3950 let next_time = current_time_millis() + RESOLVE_WAIT_IN_MILLIS;
3953 self.add_retransmission(next_time, Command::Resolve(instance, try_count + 1));
3954 }
3955 }
3956
3957 fn exec_command_unregister(
3958 &mut self,
3959 repeating: bool,
3960 fullname: String,
3961 resp_s: Sender<UnregisterStatus>,
3962 ) {
3963 let response = match self.my_services.remove_entry(&fullname) {
3964 None => {
3965 debug!("unregister: cannot find such service {}", &fullname);
3966 UnregisterStatus::NotFound
3967 }
3968 Some((_k, info)) => {
3969 let mut timers = Vec::new();
3970
3971 for (if_index, intf) in self.my_intfs.iter() {
3972 if let Some(sock) = self.ipv4_sock.as_ref() {
3973 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
3974 if !repeating && !packet.is_empty() {
3976 let next_time = current_time_millis() + 120;
3977 self.retransmissions.push(ReRun {
3978 next_time,
3979 command: Command::UnregisterResend(packet, *if_index, true),
3980 });
3981 timers.push(next_time);
3982 }
3983 }
3984
3985 if let Some(sock) = self.ipv6_sock.as_ref() {
3987 let packet = self.unregister_service(&info, intf, &sock.pktinfo);
3988 if !repeating && !packet.is_empty() {
3989 let next_time = current_time_millis() + 120;
3990 self.retransmissions.push(ReRun {
3991 next_time,
3992 command: Command::UnregisterResend(packet, *if_index, false),
3993 });
3994 timers.push(next_time);
3995 }
3996 }
3997 }
3998
3999 for t in timers {
4000 self.add_timer(t);
4001 }
4002
4003 self.increase_counter(Counter::Unregister, 1);
4004 UnregisterStatus::OK
4005 }
4006 };
4007 if let Err(e) = resp_s.send(response) {
4008 debug!("unregister: failed to send response: {}", e);
4009 }
4010 }
4011
4012 fn exec_command_unregister_resend(&mut self, packet: Vec<u8>, if_index: u32, is_ipv4: bool) {
4013 let Some(intf) = self.my_intfs.get(&if_index) else {
4014 return;
4015 };
4016 let sock_opt = if is_ipv4 {
4017 &self.ipv4_sock
4018 } else {
4019 &self.ipv6_sock
4020 };
4021 let Some(sock) = sock_opt else {
4022 return;
4023 };
4024
4025 let if_addr = if is_ipv4 {
4026 match intf.next_ifaddr_v4() {
4027 Some(addr) => addr,
4028 None => return,
4029 }
4030 } else {
4031 match intf.next_ifaddr_v6() {
4032 Some(addr) => addr,
4033 None => return,
4034 }
4035 };
4036
4037 debug!("UnregisterResend from {:?}", if_addr);
4038 multicast_on_intf(
4039 &packet[..],
4040 &intf.name,
4041 intf.index,
4042 if_addr,
4043 &sock.pktinfo,
4044 self.port,
4045 );
4046
4047 self.increase_counter(Counter::UnregisterResend, 1);
4048 }
4049
4050 fn exec_command_stop_browse(&mut self, ty_domain: String) {
4051 match self.service_queriers.remove_entry(&ty_domain) {
4052 None => debug!("StopBrowse: cannot find querier for {}", &ty_domain),
4053 Some((ty, sender)) => {
4054 trace!("StopBrowse: removed queryer for {}", &ty);
4056 let mut i = 0;
4057 while i < self.retransmissions.len() {
4058 if let Command::Browse(t, _, _, _) = &self.retransmissions[i].command {
4059 if t == &ty {
4060 self.retransmissions.remove(i);
4061 trace!("StopBrowse: removed retransmission for {}", &ty);
4062 continue;
4063 }
4064 }
4065 i += 1;
4066 }
4067
4068 self.cache.remove_service_type(&ty_domain);
4070
4071 match sender.send(ServiceEvent::SearchStopped(ty_domain)) {
4073 Ok(()) => trace!("Sent SearchStopped to the listener"),
4074 Err(e) => debug!("Failed to send SearchStopped: {}", e),
4075 }
4076 }
4077 }
4078 }
4079
4080 fn exec_command_stop_resolve_hostname(&mut self, hostname: String) {
4081 if let Some((host, (sender, _timeout))) = self.hostname_resolvers.remove_entry(&hostname) {
4082 trace!("StopResolve: removed queryer for {}", &host);
4084 let mut i = 0;
4085 while i < self.retransmissions.len() {
4086 if let Command::Resolve(t, _) = &self.retransmissions[i].command {
4087 if t == &host {
4088 self.retransmissions.remove(i);
4089 trace!("StopResolve: removed retransmission for {}", &host);
4090 continue;
4091 }
4092 }
4093 i += 1;
4094 }
4095
4096 match sender.send(HostnameResolutionEvent::SearchStopped(hostname)) {
4098 Ok(()) => trace!("Sent SearchStopped to the listener"),
4099 Err(e) => debug!("Failed to send SearchStopped: {}", e),
4100 }
4101 }
4102 }
4103
4104 fn exec_command_register_resend(&mut self, fullname: String, if_index: u32) -> MyResult<()> {
4105 let Some(info) = self.my_services.get_mut(&fullname) else {
4106 trace!("announce: cannot find such service {}", &fullname);
4107 return Ok(());
4108 };
4109
4110 let Some(dns_registry) = self.dns_registry_map.get_mut(&if_index) else {
4111 return Ok(());
4112 };
4113
4114 let Some(intf) = self.my_intfs.get(&if_index) else {
4115 return Ok(());
4116 };
4117
4118 let announced_v4 = if let Some(sock) = self.ipv4_sock.as_ref() {
4119 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
4120 } else {
4121 false
4122 };
4123 let announced_v6 = if let Some(sock) = self.ipv6_sock.as_ref() {
4124 announce_service_on_intf(dns_registry, info, intf, &sock.pktinfo, self.port)?
4125 } else {
4126 false
4127 };
4128
4129 if announced_v4 || announced_v6 {
4130 let hostname = dns_registry.resolve_name(info.get_hostname());
4131 let service_name = dns_registry.resolve_name(&fullname).to_string();
4132
4133 debug!("resend: announce service {service_name} on {}", intf.name);
4134
4135 notify_monitors(
4136 &mut self.monitors,
4137 DaemonEvent::Announce(service_name, format!("{}:{}", hostname, &intf.name)),
4138 );
4139 info.set_status(if_index, ServiceStatus::Announced);
4140 } else {
4141 debug!("register-resend should not fail");
4142 }
4143
4144 self.increase_counter(Counter::RegisterResend, 1);
4145 Ok(())
4146 }
4147
4148 fn exec_command_verify(&mut self, instance: String, timeout: Duration, repeating: bool) {
4149 let now = current_time_millis();
4159 let expire_at = if repeating {
4160 None
4161 } else {
4162 Some(now + timeout.as_millis() as u64)
4163 };
4164
4165 let record_vec = self.cache.service_verify_queries(&instance, expire_at);
4167
4168 if !record_vec.is_empty() {
4169 let query_vec: Vec<(&str, RRType)> = record_vec
4170 .iter()
4171 .map(|(record, rr_type)| (record.as_str(), *rr_type))
4172 .collect();
4173 self.send_query_vec(&query_vec);
4174
4175 if let Some(new_expire) = expire_at {
4176 self.add_timer(new_expire); self.add_retransmission(now + 1000, Command::Verify(instance, timeout));
4180 }
4181 }
4182 }
4183
4184 fn refresh_active_services(&mut self) {
4186 let mut query_ptr_count = 0;
4187 let mut query_srv_count = 0;
4188 let mut new_timers = HashSet::new();
4189 let mut query_addr_count = 0;
4190
4191 for (ty_domain, _sender) in self.service_queriers.iter() {
4192 let refreshed_timers = self.cache.refresh_due_ptr(ty_domain);
4193 if !refreshed_timers.is_empty() {
4194 trace!("sending refresh query for PTR: {}", ty_domain);
4195 self.send_query(ty_domain, RRType::PTR);
4196 query_ptr_count += 1;
4197 new_timers.extend(refreshed_timers);
4198 }
4199
4200 let (instances, timers) = self.cache.refresh_due_srv_txt(ty_domain);
4201 for (instance, types) in instances {
4202 trace!("sending refresh query for: {}", &instance);
4203 let query_vec = types
4204 .into_iter()
4205 .map(|ty| (instance.as_str(), ty))
4206 .collect::<Vec<_>>();
4207 self.send_query_vec(&query_vec);
4208 query_srv_count += 1;
4209 }
4210 new_timers.extend(timers);
4211 let (hostnames, timers) = self.cache.refresh_due_hosts(ty_domain);
4212 for hostname in hostnames.iter() {
4213 trace!("sending refresh queries for A and AAAA: {}", hostname);
4214 self.send_query_vec(&[(hostname, RRType::A), (hostname, RRType::AAAA)]);
4215 query_addr_count += 2;
4216 }
4217 new_timers.extend(timers);
4218 }
4219
4220 for timer in new_timers {
4221 self.add_timer(timer);
4222 }
4223
4224 self.increase_counter(Counter::CacheRefreshPTR, query_ptr_count);
4225 self.increase_counter(Counter::CacheRefreshSrvTxt, query_srv_count);
4226 self.increase_counter(Counter::CacheRefreshAddr, query_addr_count);
4227 }
4228}
4229
4230fn add_answer_of_service(
4232 out: &mut DnsOutgoing,
4233 msg: &DnsIncoming,
4234 entry_name: &str,
4235 service: &ServiceInfo,
4236 qtype: RRType,
4237 intf_addrs: Vec<IpAddr>,
4238) {
4239 if qtype == RRType::SRV || qtype == RRType::ANY {
4240 out.add_answer(
4241 msg,
4242 DnsSrv::new(
4243 entry_name,
4244 CLASS_IN | CLASS_CACHE_FLUSH,
4245 service.get_host_ttl(),
4246 service.get_priority(),
4247 service.get_weight(),
4248 service.get_port(),
4249 service.get_hostname().to_string(),
4250 ),
4251 );
4252 }
4253
4254 if qtype == RRType::TXT || qtype == RRType::ANY {
4255 out.add_answer(
4256 msg,
4257 DnsTxt::new(
4258 entry_name,
4259 CLASS_IN | CLASS_CACHE_FLUSH,
4260 service.get_other_ttl(),
4261 service.generate_txt(),
4262 ),
4263 );
4264 }
4265
4266 if qtype == RRType::SRV {
4267 for address in intf_addrs {
4268 out.add_additional_answer(DnsAddress::new(
4269 service.get_hostname(),
4270 ip_address_rr_type(&address),
4271 CLASS_IN | CLASS_CACHE_FLUSH,
4272 service.get_host_ttl(),
4273 address,
4274 InterfaceId::default(),
4275 ));
4276 }
4277 }
4278}
4279
4280#[derive(Clone, Debug)]
4283#[non_exhaustive]
4284pub enum ServiceEvent {
4285 SearchStarted(String),
4287
4288 ServiceFound(String, String),
4290
4291 ServiceResolved(Box<ResolvedService>),
4293
4294 ServiceRemoved(String, String),
4296
4297 SearchStopped(String),
4299}
4300
4301#[derive(Clone, Debug)]
4304#[non_exhaustive]
4305pub enum HostnameResolutionEvent {
4306 SearchStarted(String),
4308 AddressesFound(String, HashSet<ScopedIp>),
4310 AddressesRemoved(String, HashSet<ScopedIp>),
4312 SearchTimeout(String),
4314 SearchStopped(String),
4316}
4317
4318#[derive(Clone, Debug)]
4321#[non_exhaustive]
4322pub enum DaemonEvent {
4323 Announce(String, String),
4325
4326 Error(Error),
4328
4329 IpAdd(IpAddr),
4331
4332 IpDel(IpAddr),
4334
4335 NameChange(DnsNameChange),
4338
4339 Respond(String),
4341}
4342
4343#[derive(Clone, Debug)]
4346pub struct DnsNameChange {
4347 pub original: String,
4349
4350 pub new_name: String,
4360
4361 pub rr_type: RRType,
4363
4364 pub intf_name: String,
4366}
4367
4368#[derive(Debug)]
4370enum Command {
4371 Browse(String, u32, bool, Sender<ServiceEvent>),
4373
4374 ResolveHostname(String, u32, Sender<HostnameResolutionEvent>, Option<u64>), Register(Box<ServiceInfo>),
4379
4380 Unregister(String, Sender<UnregisterStatus>), RegisterResend(String, u32), UnregisterResend(Vec<u8>, u32, bool), StopBrowse(String), StopResolveHostname(String), Resolve(String, u16), GetMetrics(Sender<Metrics>),
4401
4402 GetStatus(Sender<DaemonStatus>),
4404
4405 Monitor(Sender<DaemonEvent>),
4407
4408 SetOption(DaemonOption),
4409
4410 GetOption(Sender<DaemonOptionVal>),
4411
4412 Verify(String, Duration),
4417
4418 InvalidIntfAddrs(HashSet<Interface>),
4420
4421 Exit(Sender<DaemonStatus>),
4422}
4423
4424impl fmt::Display for Command {
4425 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4426 match self {
4427 Self::Browse(_, _, _, _) => write!(f, "Command Browse"),
4428 Self::ResolveHostname(_, _, _, _) => write!(f, "Command ResolveHostname"),
4429 Self::Exit(_) => write!(f, "Command Exit"),
4430 Self::GetStatus(_) => write!(f, "Command GetStatus"),
4431 Self::GetMetrics(_) => write!(f, "Command GetMetrics"),
4432 Self::Monitor(_) => write!(f, "Command Monitor"),
4433 Self::Register(_) => write!(f, "Command Register"),
4434 Self::RegisterResend(_, _) => write!(f, "Command RegisterResend"),
4435 Self::SetOption(_) => write!(f, "Command SetOption"),
4436 Self::GetOption(_) => write!(f, "Command GetOption"),
4437 Self::StopBrowse(_) => write!(f, "Command StopBrowse"),
4438 Self::StopResolveHostname(_) => write!(f, "Command StopResolveHostname"),
4439 Self::Unregister(_, _) => write!(f, "Command Unregister"),
4440 Self::UnregisterResend(_, _, _) => write!(f, "Command UnregisterResend"),
4441 Self::Resolve(_, _) => write!(f, "Command Resolve"),
4442 Self::Verify(_, _) => write!(f, "Command VerifyResource"),
4443 Self::InvalidIntfAddrs(_) => write!(f, "Command InvalidIntfAddrs"),
4444 }
4445 }
4446}
4447
4448struct DaemonOptionVal {
4449 _service_name_len_max: u8,
4450 ip_check_interval: u64,
4451}
4452
4453#[derive(Debug)]
4454enum DaemonOption {
4455 ServiceNameLenMax(u8),
4456 IpCheckInterval(u64),
4457 MaxPacketSize(Vec<IfKind>, usize),
4458 EnableInterface(Vec<IfKind>),
4459 DisableInterface(Vec<IfKind>),
4460 MulticastLoopV4(bool),
4461 MulticastLoopV6(bool),
4462 AcceptUnsolicited(bool),
4463 IncludeAppleP2P(bool),
4464 #[cfg(test)]
4465 TestDownInterface(String),
4466 #[cfg(test)]
4467 TestUpInterface(String),
4468}
4469
4470const DOMAIN_LEN: usize = "._tcp.local.".len();
4472
4473fn check_service_name_length(ty_domain: &str, limit: u8) -> Result<()> {
4475 if ty_domain.len() <= DOMAIN_LEN + 1 {
4476 return Err(e_fmt!("Service type name cannot be empty: {}", ty_domain));
4478 }
4479
4480 let service_name_len = ty_domain.len() - DOMAIN_LEN - 1; if service_name_len > limit as usize {
4482 return Err(e_fmt!("Service name length must be <= {} bytes", limit));
4483 }
4484 Ok(())
4485}
4486
4487fn check_domain_suffix(name: &str) -> Result<()> {
4489 if !(name.ends_with("._tcp.local.") || name.ends_with("._udp.local.")) {
4490 return Err(e_fmt!(
4491 "mDNS service {} must end with '._tcp.local.' or '._udp.local.'",
4492 name
4493 ));
4494 }
4495
4496 Ok(())
4497}
4498
4499fn check_service_name(fullname: &str) -> Result<()> {
4507 check_domain_suffix(fullname)?;
4508
4509 let remaining: Vec<&str> = fullname[..fullname.len() - DOMAIN_LEN].split('.').collect();
4510 let name = remaining.last().ok_or_else(|| e_fmt!("No service name"))?;
4511
4512 if &name[0..1] != "_" {
4513 return Err(e_fmt!("Service name must start with '_'"));
4514 }
4515
4516 let name = &name[1..];
4517
4518 if name.contains("--") {
4519 return Err(e_fmt!("Service name must not contain '--'"));
4520 }
4521
4522 if name.starts_with('-') || name.ends_with('-') {
4523 return Err(e_fmt!("Service name (%s) may not start or end with '-'"));
4524 }
4525
4526 let ascii_count = name.chars().filter(|c| c.is_ascii_alphabetic()).count();
4527 if ascii_count < 1 {
4528 return Err(e_fmt!(
4529 "Service name must contain at least one letter (eg: 'A-Za-z')"
4530 ));
4531 }
4532
4533 Ok(())
4534}
4535
4536fn check_hostname(hostname: &str) -> Result<()> {
4538 if !hostname.ends_with(".local.") {
4539 return Err(e_fmt!("Hostname must end with '.local.': {hostname}"));
4540 }
4541
4542 if hostname == ".local." {
4543 return Err(e_fmt!(
4544 "The part of the hostname before '.local.' cannot be empty"
4545 ));
4546 }
4547
4548 if hostname.len() > 255 {
4549 return Err(e_fmt!("Hostname length must be <= 255 bytes"));
4550 }
4551
4552 Ok(())
4553}
4554
4555fn call_service_listener(
4556 listeners_map: &HashMap<String, Sender<ServiceEvent>>,
4557 ty_domain: &str,
4558 event: ServiceEvent,
4559) {
4560 if let Some(listener) = listeners_map.get(ty_domain) {
4561 match listener.send(event) {
4562 Ok(()) => trace!("Sent event to listener successfully"),
4563 Err(e) => debug!("Failed to send event: {}", e),
4564 }
4565 }
4566}
4567
4568fn call_hostname_resolution_listener(
4569 listeners_map: &HashMap<String, (Sender<HostnameResolutionEvent>, Option<u64>)>,
4570 hostname: &str,
4571 event: HostnameResolutionEvent,
4572) {
4573 let hostname_lower = hostname.to_lowercase();
4574 if let Some(listener) = listeners_map.get(&hostname_lower).map(|(l, _)| l) {
4575 match listener.send(event) {
4576 Ok(()) => trace!("Sent event to listener successfully"),
4577 Err(e) => debug!("Failed to send event: {}", e),
4578 }
4579 }
4580}
4581
4582fn my_ip_interfaces(with_loopback: bool) -> Vec<Interface> {
4586 my_ip_interfaces_inner(with_loopback, false)
4587}
4588
4589fn my_ip_interfaces_inner(with_loopback: bool, with_apple_p2p: bool) -> Vec<Interface> {
4590 if_addrs::get_if_addrs()
4591 .unwrap_or_default()
4592 .into_iter()
4593 .filter(|i| {
4594 i.is_oper_up()
4595 && !i.is_p2p()
4596 && (!i.is_loopback() || with_loopback)
4597 && (with_apple_p2p || !is_apple_p2p_by_name(&i.name))
4598 })
4599 .collect()
4600}
4601
4602fn is_apple_p2p_by_name(name: &str) -> bool {
4605 let p2p_prefixes = ["awdl", "llw"];
4606 p2p_prefixes.iter().any(|prefix| name.starts_with(prefix))
4607}
4608
4609#[derive(Clone, Copy, Debug)]
4611struct SendConfig {
4612 port: u16,
4614
4615 max_packet_size: usize,
4618
4619 is_ipv4: bool,
4622}
4623
4624fn send_dns_outgoing(
4627 out: &DnsOutgoing,
4628 my_intf: &MyIntf,
4629 sock: &PktInfoUdpSocket,
4630 port: u16,
4631 source: Option<&IfAddr>,
4632 unicast_dest: Option<SocketAddr>,
4633) -> MyResult<Vec<Vec<u8>>> {
4634 let if_name = &my_intf.name;
4635
4636 let if_addr = match source {
4637 Some(addr) => addr,
4638 None => {
4639 if sock.domain() == Domain::IPV4 {
4640 match my_intf.next_ifaddr_v4() {
4641 Some(addr) => addr,
4642 None => return Ok(vec![]),
4643 }
4644 } else {
4645 match my_intf.next_ifaddr_v6() {
4646 Some(addr) => addr,
4647 None => return Ok(vec![]),
4648 }
4649 }
4650 }
4651 };
4652
4653 let is_ipv4 = if_addr.ip().is_ipv4();
4655 let config = SendConfig {
4656 port,
4657 max_packet_size: my_intf.max_packet_size(is_ipv4),
4658 is_ipv4,
4659 };
4660
4661 send_dns_outgoing_impl(
4662 out,
4663 if_name,
4664 my_intf.index,
4665 if_addr,
4666 sock,
4667 config,
4668 unicast_dest,
4669 )
4670}
4671
4672fn send_dns_outgoing_impl(
4674 out: &DnsOutgoing,
4675 if_name: &str,
4676 if_index: u32,
4677 if_addr: &IfAddr,
4678 sock: &PktInfoUdpSocket,
4679 config: SendConfig,
4680 unicast_dest: Option<SocketAddr>,
4681) -> MyResult<Vec<Vec<u8>>> {
4682 let qtype = if out.is_query() {
4683 "query"
4684 } else {
4685 if out.answers_count() == 0 && out.additionals().is_empty() {
4686 return Ok(vec![]); }
4688 "response"
4689 };
4690 trace!(
4691 "send {}: {} questions {} answers {} authorities {} additional",
4692 qtype,
4693 out.questions().len(),
4694 out.answers_count(),
4695 out.authorities().len(),
4696 out.additionals().len()
4697 );
4698
4699 match if_addr.ip() {
4700 IpAddr::V4(ipv4) => {
4701 if let Err(e) = sock.set_multicast_if_v4(&ipv4) {
4702 debug!(
4703 "send_dns_outgoing: failed to set multicast interface for IPv4 {}: {}",
4704 ipv4, e
4705 );
4706 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4708 let intf_addr = Interface {
4709 name: if_name.to_string(),
4710 addr: if_addr.clone(),
4711 index: Some(if_index),
4712 oper_status: if_addrs::IfOperStatus::Down,
4713 is_p2p: false,
4714 #[cfg(windows)]
4715 adapter_name: String::new(),
4716 };
4717 return Err(InternalError::IntfAddrInvalid(intf_addr));
4718 }
4719 return Ok(vec![]); }
4721 }
4722 IpAddr::V6(ipv6) => {
4723 if let Err(e) = sock.set_multicast_if_v6(if_index) {
4724 debug!(
4725 "send_dns_outgoing: failed to set multicast interface for IPv6 {}: {}",
4726 ipv6, e
4727 );
4728 if e.kind() == std::io::ErrorKind::AddrNotAvailable {
4730 let intf_addr = Interface {
4731 name: if_name.to_string(),
4732 addr: if_addr.clone(),
4733 index: Some(if_index),
4734 oper_status: if_addrs::IfOperStatus::Down,
4735 is_p2p: false,
4736 #[cfg(windows)]
4737 adapter_name: String::new(),
4738 };
4739 return Err(InternalError::IntfAddrInvalid(intf_addr));
4740 }
4741 return Ok(vec![]); }
4743 }
4744 }
4745
4746 let packet_list = out.to_data_on_wire(config.max_packet_size, config.is_ipv4);
4747 for packet in packet_list.iter() {
4748 match unicast_dest {
4749 Some(dest) => unicast_on_intf(packet, if_name, dest, sock),
4750 None => multicast_on_intf(packet, if_name, if_index, if_addr, sock, config.port),
4751 }
4752 }
4753 Ok(packet_list)
4754}
4755
4756fn unicast_on_intf(packet: &[u8], if_name: &str, dest: SocketAddr, socket: &PktInfoUdpSocket) {
4759 let max_size = max_pkt_absolute(dest.is_ipv4());
4760 if packet.len() > max_size {
4761 debug!("Drop over-sized packet ({} > {max_size})", packet.len());
4762 return;
4763 }
4764
4765 let sock_addr = dest.into();
4766 match socket.send_to(packet, &sock_addr) {
4767 Ok(sz) => trace!(
4768 "sent unicast {} bytes on interface {} to {}",
4769 sz,
4770 if_name,
4771 dest
4772 ),
4773 Err(e) => trace!(
4774 "Failed to send unicast to {} via {:?}: {}",
4775 dest,
4776 &if_name,
4777 e
4778 ),
4779 }
4780}
4781
4782fn multicast_on_intf(
4784 packet: &[u8],
4785 if_name: &str,
4786 if_index: u32,
4787 if_addr: &IfAddr,
4788 socket: &PktInfoUdpSocket,
4789 port: u16,
4790) {
4791 let max_size = max_pkt_absolute(if_addr.ip().is_ipv4());
4792 if packet.len() > max_size {
4793 debug!("Drop over-sized packet ({} > {max_size})", packet.len());
4794 return;
4795 }
4796
4797 let addr: SocketAddr = match if_addr {
4798 if_addrs::IfAddr::V4(_) => SocketAddrV4::new(GROUP_ADDR_V4, port).into(),
4799 if_addrs::IfAddr::V6(_) => {
4800 let mut sock = SocketAddrV6::new(GROUP_ADDR_V6, port, 0, 0);
4801 sock.set_scope_id(if_index); sock.into()
4803 }
4804 };
4805
4806 let sock_addr = addr.into();
4808 match socket.send_to(packet, &sock_addr) {
4809 Ok(sz) => trace!(
4810 "sent out {} bytes on interface {} (idx {}) addr {}",
4811 sz,
4812 if_name,
4813 if_index,
4814 if_addr.ip()
4815 ),
4816 Err(e) => trace!("Failed to send to {} via {:?}: {}", addr, &if_name, e),
4817 }
4818}
4819
4820fn valid_instance_name(name: &str) -> bool {
4824 name.split('.').count() >= 5
4825}
4826
4827fn notify_monitors(monitors: &mut Vec<Sender<DaemonEvent>>, event: DaemonEvent) {
4828 monitors.retain(|sender| {
4829 if let Err(e) = sender.try_send(event.clone()) {
4830 debug!("notify_monitors: try_send: {}", &e);
4831 if matches!(e, TrySendError::Disconnected(_)) {
4832 return false; }
4834 }
4835 true
4836 });
4837}
4838
4839fn prepare_announce(
4842 info: &ServiceInfo,
4843 intf: &MyIntf,
4844 dns_registry: &mut DnsRegistry,
4845 is_ipv4: bool,
4846) -> Option<DnsOutgoing> {
4847 let intf_addrs = if is_ipv4 {
4848 info.get_addrs_on_my_intf_v4(intf)
4849 } else {
4850 info.get_addrs_on_my_intf_v6(intf)
4851 };
4852
4853 if intf_addrs.is_empty() {
4854 debug!(
4855 "prepare_announce (ipv4: {is_ipv4}): no valid addrs on interface {}",
4856 &intf.name
4857 );
4858 return None;
4859 }
4860
4861 let service_fullname = dns_registry.resolve_name(info.get_fullname());
4863
4864 debug!(
4865 "prepare to announce service {service_fullname} on {:?}",
4866 &intf_addrs
4867 );
4868
4869 let mut probing_count = 0;
4870 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
4871 let create_time = current_time_millis() + fastrand::u64(0..250);
4872
4873 out.add_answer_at_time(
4874 DnsPointer::new(
4875 info.get_type(),
4876 RRType::PTR,
4877 CLASS_IN,
4878 info.get_other_ttl(),
4879 service_fullname.to_string(),
4880 ),
4881 0,
4882 );
4883
4884 if let Some(sub) = info.get_subtype() {
4885 trace!("Adding subdomain {}", sub);
4886 out.add_answer_at_time(
4887 DnsPointer::new(
4888 sub,
4889 RRType::PTR,
4890 CLASS_IN,
4891 info.get_other_ttl(),
4892 service_fullname.to_string(),
4893 ),
4894 0,
4895 );
4896 }
4897
4898 let hostname = dns_registry.resolve_name(info.get_hostname()).to_string();
4900
4901 let mut srv = DnsSrv::new(
4902 info.get_fullname(),
4903 CLASS_IN | CLASS_CACHE_FLUSH,
4904 info.get_host_ttl(),
4905 info.get_priority(),
4906 info.get_weight(),
4907 info.get_port(),
4908 hostname,
4909 );
4910
4911 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4912 srv.get_record_mut().set_new_name(new_name.to_string());
4913 }
4914
4915 if !info.requires_probe()
4916 || dns_registry.is_probing_done(&srv, info.get_fullname(), create_time)
4917 {
4918 out.add_answer_at_time(srv, 0);
4919 } else {
4920 probing_count += 1;
4921 }
4922
4923 let mut txt = DnsTxt::new(
4926 info.get_fullname(),
4927 CLASS_IN | CLASS_CACHE_FLUSH,
4928 info.get_other_ttl(),
4929 info.generate_txt(),
4930 );
4931
4932 if let Some(new_name) = dns_registry.name_changes.get(info.get_fullname()) {
4933 txt.get_record_mut().set_new_name(new_name.to_string());
4934 }
4935
4936 if !info.requires_probe()
4937 || dns_registry.is_probing_done(&txt, info.get_fullname(), create_time)
4938 {
4939 out.add_answer_at_time(txt, 0);
4940 } else {
4941 probing_count += 1;
4942 }
4943
4944 let hostname = info.get_hostname();
4947 for address in intf_addrs {
4948 let mut dns_addr = DnsAddress::new(
4949 hostname,
4950 ip_address_rr_type(&address),
4951 CLASS_IN | CLASS_CACHE_FLUSH,
4952 info.get_host_ttl(),
4953 address,
4954 intf.into(),
4955 );
4956
4957 if let Some(new_name) = dns_registry.name_changes.get(hostname) {
4958 dns_addr.get_record_mut().set_new_name(new_name.to_string());
4959 }
4960
4961 if !info.requires_probe()
4962 || dns_registry.is_probing_done(&dns_addr, info.get_fullname(), create_time)
4963 {
4964 out.add_answer_at_time(dns_addr, 0);
4965 } else {
4966 probing_count += 1;
4967 }
4968 }
4969
4970 if probing_count > 0 {
4971 return None;
4972 }
4973
4974 Some(out)
4975}
4976
4977fn announce_service_on_intf(
4980 dns_registry: &mut DnsRegistry,
4981 info: &ServiceInfo,
4982 intf: &MyIntf,
4983 sock: &PktInfoUdpSocket,
4984 port: u16,
4985) -> MyResult<bool> {
4986 let is_ipv4 = sock.domain() == Domain::IPV4;
4987 if let Some(mut out) = prepare_announce(info, intf, dns_registry, is_ipv4) {
4988 dns_registry.apply_multicast_rate_limit(&mut out, current_time_millis(), is_ipv4);
4991 if out.answers_count() > 0 {
4992 let _ = send_dns_outgoing(&out, intf, sock, port, None, None)?;
4993 }
4994 return Ok(true);
4995 }
4996
4997 Ok(false)
4998}
4999
5000fn name_change(original: &str) -> String {
5008 let mut parts: Vec<_> = original.split('.').collect();
5009 let Some(first_part) = parts.get_mut(0) else {
5010 return format!("{original} (2)");
5011 };
5012
5013 let mut new_name = format!("{first_part} (2)");
5014
5015 if let Some(paren_pos) = first_part.rfind(" (") {
5017 if let Some(end_paren) = first_part[paren_pos..].find(')') {
5019 let absolute_end_pos = paren_pos + end_paren;
5020 if absolute_end_pos == first_part.len() - 1 {
5022 let num_start = paren_pos + 2; if let Ok(number) = first_part[num_start..absolute_end_pos].parse::<u32>() {
5025 let base_name = &first_part[..paren_pos];
5026 new_name = format!("{} ({})", base_name, number + 1)
5027 }
5028 }
5029 }
5030 }
5031
5032 *first_part = &new_name;
5033 parts.join(".")
5034}
5035
5036fn hostname_change(original: &str) -> String {
5044 let mut parts: Vec<_> = original.split('.').collect();
5045 let Some(first_part) = parts.get_mut(0) else {
5046 return format!("{original}-2");
5047 };
5048
5049 let mut new_name = format!("{first_part}-2");
5050
5051 if let Some(hyphen_pos) = first_part.rfind('-') {
5053 if let Ok(number) = first_part[hyphen_pos + 1..].parse::<u32>() {
5055 let base_name = &first_part[..hyphen_pos];
5056 new_name = format!("{}-{}", base_name, number + 1);
5057 }
5058 }
5059
5060 *first_part = &new_name;
5061 parts.join(".")
5062}
5063
5064fn check_probing(
5067 dns_registry: &mut DnsRegistry,
5068 timers: &mut BinaryHeap<Reverse<u64>>,
5069 now: u64,
5070) -> (DnsOutgoing, Vec<String>) {
5071 let mut expired_probes = Vec::new();
5072 let mut out = DnsOutgoing::new(FLAGS_QR_QUERY);
5073
5074 for (name, probe) in dns_registry.probing.iter_mut() {
5075 if now >= probe.next_send {
5076 if probe.expired(now) {
5077 expired_probes.push(name.clone());
5079 } else {
5080 out.add_question(name, RRType::ANY);
5081
5082 for record in probe.records.iter() {
5090 out.add_authority(record.clone());
5091 }
5092
5093 probe.update_next_send(now);
5094
5095 timers.push(Reverse(probe.next_send));
5097 }
5098 }
5099 }
5100
5101 (out, expired_probes)
5102}
5103
5104fn handle_expired_probes(
5109 expired_probes: Vec<String>,
5110 intf_name: &str,
5111 dns_registry: &mut DnsRegistry,
5112 monitors: &mut Vec<Sender<DaemonEvent>>,
5113) -> HashSet<String> {
5114 let mut waiting_services = HashSet::new();
5115
5116 for name in expired_probes {
5117 let Some(probe) = dns_registry.probing.remove(&name) else {
5118 continue;
5119 };
5120
5121 for record in probe.records.iter() {
5123 if let Some(new_name) = record.get_record().get_new_name() {
5124 dns_registry
5125 .name_changes
5126 .insert(name.clone(), new_name.to_string());
5127
5128 let event = DnsNameChange {
5129 original: record.get_record().get_original_name().to_string(),
5130 new_name: new_name.to_string(),
5131 rr_type: record.get_type(),
5132 intf_name: intf_name.to_string(),
5133 };
5134 debug!("Name change event: {:?}", &event);
5135 notify_monitors(monitors, DaemonEvent::NameChange(event));
5136 }
5137 }
5138
5139 debug!(
5141 "probe of '{name}' finished: move {} records to active. ({} waiting services)",
5142 probe.records.len(),
5143 probe.waiting_services.len(),
5144 );
5145
5146 if !probe.records.is_empty() {
5148 match dns_registry.active.get_mut(&name) {
5149 Some(records) => {
5150 records.extend(probe.records);
5151 }
5152 None => {
5153 dns_registry.active.insert(name, probe.records);
5154 }
5155 }
5156
5157 waiting_services.extend(probe.waiting_services);
5158 }
5159 }
5160
5161 waiting_services
5162}
5163
5164fn resolve_max_packet_size(
5172 selections: &[MaxPacketSizeSelection],
5173 interfaces: &[Interface],
5174 if_index: u32,
5175 is_ipv4: bool,
5176) -> usize {
5177 let mut size = MAX_PKT_DEFAULT;
5178
5179 for selection in selections {
5180 let matched = interfaces.iter().any(|intf| {
5181 intf.index.unwrap_or(0) == if_index
5182 && intf.ip().is_ipv4() == is_ipv4
5183 && selection.if_kind.matches(intf)
5184 });
5185 if matched {
5186 size = selection.max_packet_size;
5187 }
5188 }
5189
5190 size
5191}
5192
5193fn resolve_addr_to_index(if_kind: IfKind, interfaces: &[Interface]) -> IfKind {
5195 if let IfKind::Addr(addr) = &if_kind {
5196 if let Some(intf) = interfaces.iter().find(|intf| &intf.ip() == addr) {
5197 let if_index = intf.index.unwrap_or(0);
5198 return if addr.is_ipv4() {
5199 IfKind::IndexV4(if_index)
5200 } else {
5201 IfKind::IndexV6(if_index)
5202 };
5203 }
5204 }
5205 if_kind
5206}
5207
5208#[cfg(test)]
5209mod tests {
5210 use super::{
5211 _new_socket_bind, check_domain_suffix, check_service_name_length, hostname_change,
5212 my_ip_interfaces, name_change, resolve_max_packet_size, send_dns_outgoing_impl,
5213 valid_instance_name, valid_ip_on_intf, DaemonEvent, HostnameResolutionEvent, IfKind,
5214 MaxPacketSizeSelection, MyIntf, SendConfig, ServiceDaemon, ServiceEvent, ServiceInfo,
5215 GROUP_ADDR_V4, INITIAL_QUERY_DELAY_MAX_MILLIS, INITIAL_QUERY_DELAY_MIN_MILLIS,
5216 MAX_PKT_ABSOLUTE_IPV6, MAX_PKT_DEFAULT, MDNS_PORT, MIN_MAX_PACKET_SIZE,
5217 SHARED_RESPONSE_DELAY_MAX_MILLIS, SHARED_RESPONSE_DELAY_MIN_MILLIS,
5218 };
5219 use crate::{
5220 dns_parser::{
5221 DnsEntryExt, DnsIncoming, DnsOutgoing, DnsPointer, InterfaceId, RRType, ScopedIp,
5222 CLASS_IN, FLAGS_AA, FLAGS_QR_QUERY, FLAGS_QR_RESPONSE,
5223 },
5224 service_daemon::{add_answer_of_service, check_hostname},
5225 };
5226 use if_addrs::{IfAddr, Ifv4Addr, Ifv6Addr, Interface};
5227 use std::{
5228 collections::HashSet,
5229 net::{IpAddr, Ipv4Addr, Ipv6Addr, UdpSocket},
5230 time::{Duration, Instant, SystemTime},
5231 };
5232 use test_log::test;
5233
5234 fn test_interface(name: &str, index: u32, addr: IfAddr) -> Interface {
5236 Interface {
5237 name: name.to_string(),
5238 addr,
5239 index: Some(index),
5240 oper_status: if_addrs::IfOperStatus::Up,
5241 is_p2p: false,
5242 #[cfg(windows)]
5243 adapter_name: String::new(),
5244 }
5245 }
5246
5247 fn test_ifaddr_v4(ip: Ipv4Addr) -> IfAddr {
5248 IfAddr::V4(Ifv4Addr {
5249 ip,
5250 netmask: Ipv4Addr::new(255, 255, 255, 0),
5251 broadcast: None,
5252 prefixlen: 24,
5253 })
5254 }
5255
5256 fn test_ifaddr_v6(ip: Ipv6Addr) -> IfAddr {
5257 IfAddr::V6(Ifv6Addr {
5258 ip,
5259 netmask: Ipv6Addr::from(u128::MAX << 64),
5260 broadcast: None,
5261 prefixlen: 64,
5262 })
5263 }
5264
5265 #[test]
5266 fn test_resolve_max_packet_size() {
5267 let interfaces = vec![
5269 test_interface("en0", 1, test_ifaddr_v4(Ipv4Addr::new(192, 168, 1, 2))),
5270 test_interface(
5271 "en0",
5272 1,
5273 test_ifaddr_v6(Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1)),
5274 ),
5275 test_interface("en1", 2, test_ifaddr_v4(Ipv4Addr::new(10, 0, 0, 2))),
5276 ];
5277
5278 let resolve = |selections: &[MaxPacketSizeSelection], if_index, is_ipv4| {
5279 resolve_max_packet_size(selections, &interfaces, if_index, is_ipv4)
5280 };
5281
5282 assert_eq!(resolve(&[], 1, true), MAX_PKT_DEFAULT);
5284 assert_eq!(resolve(&[], 1, false), MAX_PKT_DEFAULT);
5285
5286 let by_name = vec![MaxPacketSizeSelection {
5288 if_kind: IfKind::Name("en0".to_string()),
5289 max_packet_size: 8000,
5290 }];
5291 assert_eq!(resolve(&by_name, 1, true), 8000);
5292 assert_eq!(resolve(&by_name, 1, false), 8000);
5293 assert_eq!(resolve(&by_name, 2, true), MAX_PKT_DEFAULT);
5294
5295 let overlapping = vec![
5297 MaxPacketSizeSelection {
5298 if_kind: IfKind::All,
5299 max_packet_size: 8000,
5300 },
5301 MaxPacketSizeSelection {
5302 if_kind: IfKind::Name("en1".to_string()),
5303 max_packet_size: 4000,
5304 },
5305 ];
5306 assert_eq!(resolve(&overlapping, 1, true), 8000);
5307 assert_eq!(resolve(&overlapping, 1, false), 8000);
5308 assert_eq!(resolve(&overlapping, 2, true), 4000);
5309
5310 let v4_only = vec![MaxPacketSizeSelection {
5312 if_kind: IfKind::IPv4,
5313 max_packet_size: 8000,
5314 }];
5315 assert_eq!(resolve(&v4_only, 1, true), 8000);
5316 assert_eq!(resolve(&v4_only, 1, false), MAX_PKT_DEFAULT);
5317
5318 let v6_only = vec![MaxPacketSizeSelection {
5319 if_kind: IfKind::IPv6,
5320 max_packet_size: 8000,
5321 }];
5322 assert_eq!(resolve(&v6_only, 1, false), 8000);
5323 assert_eq!(resolve(&v6_only, 1, true), MAX_PKT_DEFAULT);
5324 assert_eq!(resolve(&v6_only, 2, true), MAX_PKT_DEFAULT);
5326 assert_eq!(resolve(&v6_only, 2, false), MAX_PKT_DEFAULT);
5327
5328 let by_index_v4 = vec![MaxPacketSizeSelection {
5330 if_kind: IfKind::IndexV4(1),
5331 max_packet_size: 8000,
5332 }];
5333 assert_eq!(resolve(&by_index_v4, 1, true), 8000);
5334 assert_eq!(resolve(&by_index_v4, 1, false), MAX_PKT_DEFAULT);
5335 }
5336
5337 #[test]
5340 fn test_set_max_packet_size_range() {
5341 let daemon = ServiceDaemon::new().unwrap();
5342
5343 assert!(daemon
5344 .set_max_packet_size(IfKind::All, MIN_MAX_PACKET_SIZE - 1)
5345 .is_err());
5346 assert!(daemon
5347 .set_max_packet_size(IfKind::All, MAX_PKT_ABSOLUTE_IPV6 + 1)
5348 .is_err());
5349
5350 assert!(daemon
5352 .set_max_packet_size(IfKind::All, MIN_MAX_PACKET_SIZE)
5353 .is_ok());
5354 assert!(daemon
5355 .set_max_packet_size(IfKind::All, MAX_PKT_ABSOLUTE_IPV6)
5356 .is_ok());
5357
5358 daemon.shutdown().unwrap();
5359 }
5360
5361 #[test]
5362 fn test_response_source_ifaddr_match() {
5363 let ifaddr_a = IfAddr::V4(Ifv4Addr {
5367 ip: Ipv4Addr::new(192, 168, 1, 148),
5368 netmask: Ipv4Addr::new(255, 255, 255, 0),
5369 broadcast: None,
5370 prefixlen: 24,
5371 });
5372 let ifaddr_b = IfAddr::V4(Ifv4Addr {
5373 ip: Ipv4Addr::new(10, 238, 0, 51),
5374 netmask: Ipv4Addr::new(255, 255, 255, 0),
5375 broadcast: None,
5376 prefixlen: 24,
5377 });
5378
5379 let intf = MyIntf {
5380 name: "dummy0".to_string(),
5381 index: 1,
5382 addrs: HashSet::from([ifaddr_a.clone(), ifaddr_b.clone()]),
5383 max_packet_size_v4: MAX_PKT_DEFAULT,
5384 max_packet_size_v6: MAX_PKT_DEFAULT,
5385 };
5386
5387 let pick = |querier: IpAddr| -> Option<IfAddr> {
5388 intf.addrs
5389 .iter()
5390 .find(|a| valid_ip_on_intf(&querier, a))
5391 .cloned()
5392 };
5393
5394 assert_eq!(
5395 pick(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 2))),
5396 Some(ifaddr_a)
5397 );
5398 assert_eq!(
5399 pick(IpAddr::V4(Ipv4Addr::new(10, 238, 0, 99))),
5400 Some(ifaddr_b)
5401 );
5402 assert_eq!(pick(IpAddr::V4(Ipv4Addr::new(172, 16, 0, 1))), None);
5404 }
5405
5406 #[test]
5407 fn test_instance_name() {
5408 assert!(valid_instance_name("my-laser._printer._tcp.local."));
5409 assert!(valid_instance_name("my-laser.._printer._tcp.local."));
5410 assert!(!valid_instance_name("_printer._tcp.local."));
5411 }
5412
5413 #[test]
5414 fn test_legacy_unicast_response() {
5415 let intf_ip = match my_ip_interfaces(false)
5426 .into_iter()
5427 .find_map(|intf| match intf.ip() {
5428 IpAddr::V4(ip) => Some(ip),
5429 IpAddr::V6(_) => None,
5430 }) {
5431 Some(ip) => ip,
5432 None => {
5433 println!("No IPv4 interface available; skipping test.");
5434 return;
5435 }
5436 };
5437
5438 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5440 let unique = SystemTime::now()
5441 .duration_since(SystemTime::UNIX_EPOCH)
5442 .unwrap()
5443 .as_micros();
5444 let hostname = format!("legacy-unicast-test-{unique}.local.");
5445 let service_info = ServiceInfo::new(
5446 "_legacy-uni._udp.local.",
5447 "test_instance",
5448 &hostname,
5449 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5450 5353, None,
5452 )
5453 .expect("invalid service info");
5454 daemon.register(service_info).expect("register service");
5455
5456 let querier = UdpSocket::bind((intf_ip, 0)).expect("bind querier socket");
5460 querier
5461 .set_multicast_loop_v4(true)
5462 .expect("enable multicast loopback");
5463 querier
5464 .set_read_timeout(Some(Duration::from_millis(500)))
5465 .expect("set read timeout");
5466 assert_ne!(
5467 querier.local_addr().unwrap().port(),
5468 MDNS_PORT,
5469 "querier must use an ephemeral (non-5353) source port"
5470 );
5471
5472 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5474 query.add_question(&hostname, RRType::A);
5475 let query_packet = query
5476 .to_data_on_wire(MAX_PKT_DEFAULT, true)
5477 .pop()
5478 .expect("query serialized to one packet");
5479
5480 let if_id = InterfaceId {
5481 name: "test".to_string(),
5482 index: 0,
5483 };
5484
5485 let deadline = Instant::now() + Duration::from_secs(8);
5488 let mut response = None;
5489 'outer: while Instant::now() < deadline {
5490 querier
5491 .send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5492 .expect("send query");
5493
5494 let mut buf = [0u8; 1500];
5497 while let Ok((len, from)) = querier.recv_from(&mut buf) {
5498 let Ok(msg) = DnsIncoming::new(buf[..len].to_vec(), if_id.clone()) else {
5499 continue;
5500 };
5501 if msg.is_response()
5502 && msg
5503 .answers()
5504 .iter()
5505 .any(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5506 {
5507 response = Some((msg, from));
5508 break 'outer;
5509 }
5510 }
5511 }
5512
5513 let (msg, from) = response.expect(
5514 "expected a unicast response to the legacy query; \
5515 a multicast-only reply would never reach this un-joined socket",
5516 );
5517
5518 assert_eq!(
5520 from.port(),
5521 MDNS_PORT,
5522 "response should originate from the mDNS port"
5523 );
5524
5525 assert!(
5527 msg.questions()
5528 .iter()
5529 .any(|q| q.entry_name().eq_ignore_ascii_case(&hostname)),
5530 "legacy unicast response must echo the question section"
5531 );
5532
5533 let answer = msg
5536 .answers()
5537 .iter()
5538 .find(|a| a.get_name().eq_ignore_ascii_case(&hostname))
5539 .expect("response contains an answer for our hostname");
5540 assert_eq!(
5541 answer.get_type(),
5542 RRType::A,
5543 "an A query should be answered with an A record"
5544 );
5545 assert!(
5546 !answer.get_cache_flush(),
5547 "legacy unicast responses must clear the cache-flush bit"
5548 );
5549
5550 daemon.shutdown().unwrap();
5551 }
5552
5553 #[test]
5554 fn test_shared_response_delay_bounds() {
5555 assert_eq!(SHARED_RESPONSE_DELAY_MIN_MILLIS, 10);
5560 assert_eq!(SHARED_RESPONSE_DELAY_MAX_MILLIS, 50);
5561 for _ in 0..10_000 {
5562 let d =
5563 fastrand::u64(SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS);
5564 assert!(
5565 (SHARED_RESPONSE_DELAY_MIN_MILLIS..SHARED_RESPONSE_DELAY_MAX_MILLIS).contains(&d),
5566 "delay {} ms is outside the configured {}-{} ms range",
5567 d,
5568 SHARED_RESPONSE_DELAY_MIN_MILLIS,
5569 SHARED_RESPONSE_DELAY_MAX_MILLIS
5570 );
5571 }
5572 }
5573
5574 #[test]
5575 fn test_initial_query_delayed() {
5576 use socket2::{Domain, Protocol, Socket, Type};
5583
5584 let (intf, intf_ip) = match my_ip_interfaces(false)
5585 .into_iter()
5586 .find_map(|intf| match intf.ip() {
5587 IpAddr::V4(ip) if !ip.is_loopback() => Some((intf, ip)),
5588 _ => None,
5589 }) {
5590 Some(pair) => pair,
5591 None => {
5592 println!("No IPv4 interface available; skipping test.");
5593 return;
5594 }
5595 };
5596 let interface_id = InterfaceId::from(&intf);
5597
5598 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5602 sock.set_reuse_address(true).unwrap();
5603 #[cfg(unix)]
5604 sock.set_reuse_port(true).unwrap();
5605 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5606 .unwrap();
5607 sock.join_multicast_v4(&GROUP_ADDR_V4, &intf_ip).unwrap();
5608 sock.set_read_timeout(Some(Duration::from_millis(200)))
5609 .unwrap();
5610 let sock: UdpSocket = sock.into();
5611
5612 let unique = SystemTime::now()
5614 .duration_since(SystemTime::UNIX_EPOCH)
5615 .unwrap()
5616 .as_micros()
5617 % 1_000_000_000;
5618 let service_type = format!("_qd{unique}._udp.local.");
5619
5620 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5621
5622 let sent_at = Instant::now();
5623 let _browse = daemon.browse(&service_type).expect("browse");
5624
5625 let deadline = Instant::now() + Duration::from_secs(2);
5628 let mut buf = [0u8; 2048];
5629 let mut measured = None;
5630 while Instant::now() < deadline {
5631 let n = match sock.recv_from(&mut buf) {
5632 Ok((n, _)) => n,
5633 Err(_) => continue, };
5635 let Ok(msg) = DnsIncoming::new(buf[..n].to_vec(), interface_id.clone()) else {
5636 continue;
5637 };
5638 if msg.is_query()
5639 && msg
5640 .questions()
5641 .iter()
5642 .any(|q| q.entry_name() == service_type)
5643 {
5644 measured = Some(sent_at.elapsed());
5645 break;
5646 }
5647 }
5648
5649 daemon.shutdown().unwrap();
5650
5651 let elapsed = measured.expect("expected the daemon to send a PTR query for our browse");
5652 let tolerance = Duration::from_millis(2);
5653 assert!(
5654 elapsed + tolerance >= Duration::from_millis(INITIAL_QUERY_DELAY_MIN_MILLIS),
5655 "first browse query was sent after only {:?}; the first query of a series must be \
5656 delayed (10-50 ms window), not sent immediately",
5657 elapsed
5658 );
5659
5660 let scheduling_slack = Duration::from_millis(50);
5665 assert!(
5666 elapsed <= Duration::from_millis(INITIAL_QUERY_DELAY_MAX_MILLIS) + scheduling_slack,
5667 "first browse query was sent after {:?}, beyond the {}-{} ms jitter window (plus slack)",
5668 elapsed,
5669 INITIAL_QUERY_DELAY_MIN_MILLIS,
5670 INITIAL_QUERY_DELAY_MAX_MILLIS
5671 );
5672 }
5673
5674 #[test]
5675 fn test_shared_ptr_response_delayed() {
5676 use socket2::{Domain, Protocol, Socket, Type};
5683
5684 let intf_ip = match my_ip_interfaces(false)
5685 .into_iter()
5686 .find_map(|intf| match intf.ip() {
5687 IpAddr::V4(ip) if !ip.is_loopback() => Some(ip),
5688 _ => None,
5689 }) {
5690 Some(ip) => ip,
5691 None => {
5692 println!("No IPv4 interface available; skipping test.");
5693 return;
5694 }
5695 };
5696
5697 let daemon = ServiceDaemon::new().expect("Failed to create daemon");
5698 let monitor = daemon.monitor().expect("monitor daemon events");
5699
5700 let unique = SystemTime::now()
5703 .duration_since(SystemTime::UNIX_EPOCH)
5704 .unwrap()
5705 .as_micros()
5706 % 1_000_000_000;
5707 let service_type = format!("_sd{unique}._udp.local.");
5708 let hostname = format!("sd{unique}.local.");
5709 let service_info = ServiceInfo::new(
5710 &service_type,
5711 "test_instance",
5712 &hostname,
5713 &[IpAddr::V4(intf_ip)] as &[IpAddr],
5714 5353,
5715 None,
5716 )
5717 .expect("invalid service info");
5718 daemon.register(service_info).expect("register service");
5719
5720 let sock = Socket::new(Domain::IPV4, Type::DGRAM, Some(Protocol::UDP)).unwrap();
5724 sock.set_reuse_address(true).unwrap();
5725 #[cfg(unix)]
5726 sock.set_reuse_port(true).unwrap();
5727 sock.bind(&std::net::SocketAddr::from((Ipv4Addr::UNSPECIFIED, MDNS_PORT)).into())
5728 .unwrap();
5729 sock.set_multicast_if_v4(&intf_ip).unwrap();
5730 sock.set_multicast_loop_v4(true).unwrap();
5732 let sock: UdpSocket = sock.into();
5733
5734 let mut query = DnsOutgoing::new(FLAGS_QR_QUERY);
5736 query.add_question(&service_type, RRType::PTR);
5737 let query_packet = query
5738 .to_data_on_wire(MAX_PKT_DEFAULT, true)
5739 .pop()
5740 .expect("one packet");
5741
5742 std::thread::sleep(Duration::from_secs(3));
5746
5747 let deadline = Instant::now() + Duration::from_secs(8);
5751 let mut measured = None;
5752 while Instant::now() < deadline {
5753 while monitor.try_recv().is_ok() {}
5756
5757 let sent_at = Instant::now();
5758 sock.send_to(&query_packet, (GROUP_ADDR_V4, MDNS_PORT))
5759 .expect("send query");
5760
5761 let attempt_deadline = sent_at + Duration::from_millis(700);
5764 loop {
5765 let remaining = attempt_deadline.saturating_duration_since(Instant::now());
5766 if remaining.is_zero() {
5767 break;
5768 }
5769 match monitor.recv_timeout(remaining) {
5770 Ok(DaemonEvent::Respond(_)) => {
5771 measured = Some(sent_at.elapsed());
5772 break;
5773 }
5774 Ok(_) => continue, Err(_) => break, }
5777 }
5778 if measured.is_some() {
5779 break;
5780 }
5781 }
5782
5783 let elapsed =
5784 measured.expect("expected the daemon to respond to our PTR query within the deadline");
5785 assert!(
5786 elapsed >= Duration::from_millis(8),
5787 "PTR response was sent after only {:?}; a shared-record response must be \
5788 delayed (10-50 ms window), not sent immediately",
5789 elapsed
5790 );
5791 assert!(
5792 elapsed <= Duration::from_millis(600),
5793 "PTR response was sent after {:?}; expected within the 10-50 ms delay window",
5794 elapsed
5795 );
5796
5797 daemon.shutdown().unwrap();
5798 }
5799
5800 #[test]
5801 fn test_check_service_name_length() {
5802 let result = check_service_name_length("_tcp", 100);
5803 assert!(result.is_err());
5804 if let Err(e) = result {
5805 println!("{}", e);
5806 }
5807 }
5808
5809 #[test]
5810 fn test_check_hostname() {
5811 for hostname in &[
5813 "my_host.local.",
5814 &("A".repeat(255 - ".local.".len()) + ".local."),
5815 ] {
5816 let result = check_hostname(hostname);
5817 assert!(result.is_ok());
5818 }
5819
5820 for hostname in &[
5822 "my_host.local",
5823 ".local.",
5824 &("A".repeat(256 - ".local.".len()) + ".local."),
5825 ] {
5826 let result = check_hostname(hostname);
5827 assert!(result.is_err());
5828 if let Err(e) = result {
5829 println!("{}", e);
5830 }
5831 }
5832 }
5833
5834 #[test]
5835 fn test_check_domain_suffix() {
5836 assert!(check_domain_suffix("_missing_dot._tcp.local").is_err());
5837 assert!(check_domain_suffix("_missing_bar.tcp.local.").is_err());
5838 assert!(check_domain_suffix("_mis_spell._tpp.local.").is_err());
5839 assert!(check_domain_suffix("_mis_spell._upp.local.").is_err());
5840 assert!(check_domain_suffix("_has_dot._tcp.local.").is_ok());
5841 assert!(check_domain_suffix("_goodname._udp.local.").is_ok());
5842 }
5843
5844 #[test]
5845 fn test_service_with_temporarily_invalidated_ptr() {
5846 let d = ServiceDaemon::new().expect("Failed to create daemon");
5848
5849 let service = "_test_inval_ptr._udp.local.";
5850 let host_name = "my_host_tmp_invalidated_ptr.local.";
5851 let intfs: Vec<_> = my_ip_interfaces(false);
5852 let intf_ips: Vec<_> = intfs.iter().map(|intf| intf.ip()).collect();
5853 let port = 5201;
5854 let my_service =
5855 ServiceInfo::new(service, "my_instance", host_name, &intf_ips[..], port, None)
5856 .expect("invalid service info")
5857 .enable_addr_auto();
5858 let result = d.register(my_service.clone());
5859 assert!(result.is_ok());
5860
5861 let browse_chan = d.browse(service).unwrap();
5863 let timeout = Duration::from_secs(2);
5864 let mut resolved = false;
5865
5866 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5867 match event {
5868 ServiceEvent::ServiceResolved(info) => {
5869 resolved = true;
5870 println!("Resolved a service of {}", &info.fullname);
5871 break;
5872 }
5873 e => {
5874 println!("Received event {:?}", e);
5875 }
5876 }
5877 }
5878
5879 assert!(resolved);
5880
5881 println!("Stopping browse of {}", service);
5882 d.stop_browse(service).unwrap();
5885
5886 let mut stopped = false;
5891 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5892 match event {
5893 ServiceEvent::SearchStopped(_) => {
5894 stopped = true;
5895 println!("Stopped browsing service");
5896 break;
5897 }
5898 e => {
5902 println!("Received event {:?}", e);
5903 }
5904 }
5905 }
5906
5907 assert!(stopped);
5908
5909 let invalidate_ptr_packet = DnsPointer::new(
5911 my_service.get_type(),
5912 RRType::PTR,
5913 CLASS_IN,
5914 0,
5915 my_service.get_fullname().to_string(),
5916 );
5917
5918 let mut packet_buffer = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
5919 packet_buffer.add_additional_answer(invalidate_ptr_packet);
5920
5921 for intf in intfs {
5922 let sock = _new_socket_bind(&intf, true).unwrap();
5923 send_dns_outgoing_impl(
5924 &packet_buffer,
5925 &intf.name,
5926 intf.index.unwrap_or(0),
5927 &intf.addr,
5928 &sock.pktinfo,
5929 SendConfig {
5930 port: MDNS_PORT,
5931 max_packet_size: MAX_PKT_DEFAULT,
5932 is_ipv4: intf.addr.ip().is_ipv4(),
5933 },
5934 None,
5935 )
5936 .unwrap();
5937 }
5938
5939 println!(
5940 "Sent PTR record invalidation. Starting second browse for {}",
5941 service
5942 );
5943
5944 let browse_chan = d.browse(service).unwrap();
5946
5947 resolved = false;
5948 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5949 match event {
5950 ServiceEvent::ServiceResolved(info) => {
5951 resolved = true;
5952 println!("Resolved a service of {}", &info.fullname);
5953 break;
5954 }
5955 e => {
5956 println!("Received event {:?}", e);
5957 }
5958 }
5959 }
5960
5961 assert!(resolved);
5962 d.shutdown().unwrap();
5963 }
5964
5965 #[test]
5966 fn test_expired_srv() {
5967 let service_type = "_expired-srv._udp.local.";
5969 let instance = "test_instance";
5970 let host_name = "expired_srv_host.local.";
5971 let mut my_service = ServiceInfo::new(service_type, instance, host_name, "", 5023, None)
5972 .unwrap()
5973 .enable_addr_auto();
5974 let new_ttl = 3; my_service._set_host_ttl(new_ttl);
5979
5980 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
5982 let result = mdns_server.register(my_service);
5983 assert!(result.is_ok());
5984
5985 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
5986 let browse_chan = mdns_client.browse(service_type).unwrap();
5987 let timeout = Duration::from_secs(2);
5988 let mut resolved = false;
5989
5990 while let Ok(event) = browse_chan.recv_timeout(timeout) {
5991 if let ServiceEvent::ServiceResolved(info) = event {
5992 resolved = true;
5993 println!("Resolved a service of {}", &info.fullname);
5994 break;
5995 }
5996 }
5997
5998 assert!(resolved);
5999
6000 mdns_server.shutdown().unwrap();
6002
6003 let expire_timeout = Duration::from_secs(new_ttl as u64);
6005 while let Ok(event) = browse_chan.recv_timeout(expire_timeout) {
6006 if let ServiceEvent::ServiceRemoved(service_type, full_name) = event {
6007 println!("Service removed: {}: {}", &service_type, &full_name);
6008 break;
6009 }
6010 }
6011 }
6012
6013 #[test]
6014 fn test_hostname_resolution_address_removed() {
6015 let server = ServiceDaemon::new().expect("Failed to create server");
6017 let hostname = "addr_remove_host._tcp.local.";
6018 let service_ip_addr: ScopedIp = my_ip_interfaces(false)
6019 .iter()
6020 .find(|iface| iface.ip().is_ipv4())
6021 .map(|iface| iface.into())
6022 .unwrap();
6023
6024 let mut my_service = ServiceInfo::new(
6025 "_host_res_test._tcp.local.",
6026 "my_instance",
6027 hostname,
6028 service_ip_addr.to_ip_addr(),
6029 1234,
6030 None,
6031 )
6032 .expect("invalid service info");
6033
6034 let addr_ttl = 2;
6036 my_service._set_host_ttl(addr_ttl); server.register(my_service).unwrap();
6039
6040 let client = ServiceDaemon::new().expect("Failed to create client");
6042 let event_receiver = client.resolve_hostname(hostname, None).unwrap();
6043 let resolved = loop {
6044 match event_receiver.recv() {
6045 Ok(HostnameResolutionEvent::AddressesFound(found_hostname, addresses)) => {
6046 assert!(found_hostname == hostname);
6047 assert!(addresses.contains(&service_ip_addr));
6048 println!("address found: {:?}", &addresses);
6049 break true;
6050 }
6051 Ok(HostnameResolutionEvent::SearchStopped(_)) => break false,
6052 Ok(_event) => {}
6053 Err(_) => break false,
6054 }
6055 };
6056
6057 assert!(resolved);
6058
6059 server.shutdown().unwrap();
6061
6062 let timeout = Duration::from_secs(addr_ttl as u64 + 1);
6064 let removed = loop {
6065 match event_receiver.recv_timeout(timeout) {
6066 Ok(HostnameResolutionEvent::AddressesRemoved(removed_host, addresses)) => {
6067 assert!(removed_host == hostname);
6068 assert!(addresses.contains(&service_ip_addr));
6069
6070 println!(
6071 "address removed: hostname: {} addresses: {:?}",
6072 &hostname, &addresses
6073 );
6074 break true;
6075 }
6076 Ok(_event) => {}
6077 Err(_) => {
6078 break false;
6079 }
6080 }
6081 };
6082
6083 assert!(removed);
6084
6085 client.shutdown().unwrap();
6086 }
6087
6088 #[test]
6089 fn test_refresh_ptr() {
6090 let service_type = "_refresh-ptr._udp.local.";
6092 let instance = "test_instance";
6093 let host_name = "refresh_ptr_host.local.";
6094 let service_ip_addr = my_ip_interfaces(false)
6095 .iter()
6096 .find(|iface| iface.ip().is_ipv4())
6097 .map(|iface| iface.ip())
6098 .unwrap();
6099
6100 let mut my_service = ServiceInfo::new(
6101 service_type,
6102 instance,
6103 host_name,
6104 service_ip_addr,
6105 5023,
6106 None,
6107 )
6108 .unwrap();
6109
6110 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
6112
6113 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6115 let result = mdns_server.register(my_service);
6116 assert!(result.is_ok());
6117
6118 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6119 let browse_chan = mdns_client.browse(service_type).unwrap();
6120 let timeout = Duration::from_millis(1500); let mut resolved = false;
6122
6123 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6125 if let ServiceEvent::ServiceResolved(info) = event {
6126 resolved = true;
6127 println!("Resolved a service of {}", &info.fullname);
6128 break;
6129 }
6130 }
6131
6132 assert!(resolved);
6133
6134 let timeout = Duration::from_millis(new_ttl as u64 * 1000 * 90 / 100);
6136 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6137 println!("event: {:?}", &event);
6138 }
6139
6140 let metrics_chan = mdns_client.get_metrics().unwrap();
6142 let metrics = metrics_chan.recv_timeout(timeout).unwrap();
6143 let ptr_refresh_counter = metrics["cache-refresh-ptr"];
6144 assert_eq!(ptr_refresh_counter, 1);
6145 let srvtxt_refresh_counter = metrics["cache-refresh-srv-txt"];
6146 assert_eq!(srvtxt_refresh_counter, 1);
6147
6148 mdns_server.shutdown().unwrap();
6150 mdns_client.shutdown().unwrap();
6151 }
6152
6153 #[test]
6154 fn test_name_change() {
6155 assert_eq!(name_change("foo.local."), "foo (2).local.");
6156 assert_eq!(name_change("foo (2).local."), "foo (3).local.");
6157 assert_eq!(name_change("foo (9).local."), "foo (10).local.");
6158 assert_eq!(name_change("foo"), "foo (2)");
6159 assert_eq!(name_change("foo (2)"), "foo (3)");
6160 assert_eq!(name_change(""), " (2)");
6161
6162 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)"); }
6167
6168 #[test]
6169 fn test_hostname_change() {
6170 assert_eq!(hostname_change("foo.local."), "foo-2.local.");
6171 assert_eq!(hostname_change("foo"), "foo-2");
6172 assert_eq!(hostname_change("foo-2.local."), "foo-3.local.");
6173 assert_eq!(hostname_change("foo-9"), "foo-10");
6174 assert_eq!(hostname_change("test-42.domain."), "test-43.domain.");
6175 }
6176
6177 #[test]
6178 fn test_add_answer_txt_ttl() {
6179 let service_type = "_test_add_answer._udp.local.";
6181 let instance = "test_instance";
6182 let host_name = "add_answer_host.local.";
6183 let service_intf = my_ip_interfaces(false)
6184 .into_iter()
6185 .find(|iface| iface.ip().is_ipv4())
6186 .unwrap();
6187 let service_ip_addr = service_intf.ip();
6188 let my_service = ServiceInfo::new(
6189 service_type,
6190 instance,
6191 host_name,
6192 service_ip_addr,
6193 5023,
6194 None,
6195 )
6196 .unwrap();
6197
6198 let mut out = DnsOutgoing::new(FLAGS_QR_RESPONSE | FLAGS_AA);
6200
6201 let mut dummy_data = out.to_data_on_wire(MAX_PKT_DEFAULT, true);
6203 let interface_id = InterfaceId::from(&service_intf);
6204 let incoming = DnsIncoming::new(dummy_data.pop().unwrap(), interface_id).unwrap();
6205
6206 let if_addrs = vec![service_intf.ip()];
6208 add_answer_of_service(
6209 &mut out,
6210 &incoming,
6211 instance,
6212 &my_service,
6213 RRType::TXT,
6214 if_addrs,
6215 );
6216
6217 assert!(
6219 out.answers_count() > 0,
6220 "No answers added to the outgoing message"
6221 );
6222
6223 let answer = out._answers().first().unwrap();
6225 assert_eq!(answer.0.get_type(), RRType::TXT);
6226
6227 assert_eq!(answer.0.get_record().get_ttl(), my_service.get_other_ttl());
6229 }
6230
6231 #[test]
6232 fn test_interface_flip() {
6233 let ty_domain = "_intf-flip._udp.local.";
6235 let host_name = "intf_flip.local.";
6236 let now = SystemTime::now()
6237 .duration_since(SystemTime::UNIX_EPOCH)
6238 .unwrap();
6239 let instance_name = now.as_micros().to_string(); let port = 5200;
6241
6242 let (ip_addr1, intf_name) = my_ip_interfaces(false)
6244 .iter()
6245 .find(|iface| iface.ip().is_ipv4())
6246 .map(|iface| (iface.ip(), iface.name.clone()))
6247 .unwrap();
6248
6249 println!("Using interface {} with IP {}", intf_name, ip_addr1);
6250
6251 let service1 = ServiceInfo::new(ty_domain, &instance_name, host_name, ip_addr1, port, None)
6253 .expect("valid service info");
6254 let server1 = ServiceDaemon::new().expect("failed to start server");
6255 server1
6256 .register(service1)
6257 .expect("Failed to register service1");
6258
6259 std::thread::sleep(Duration::from_secs(2));
6261
6262 let client = ServiceDaemon::new().expect("failed to start client");
6264
6265 let receiver = client.browse(ty_domain).unwrap();
6266
6267 let timeout = Duration::from_secs(3);
6268 let mut got_data = false;
6269
6270 while let Ok(event) = receiver.recv_timeout(timeout) {
6271 if let ServiceEvent::ServiceResolved(_) = event {
6272 println!("Received ServiceResolved event");
6273 got_data = true;
6274 break;
6275 }
6276 }
6277
6278 assert!(got_data, "Should receive ServiceResolved event");
6279
6280 client.set_ip_check_interval(1).unwrap();
6282
6283 println!("Shutting down interface {}", &intf_name);
6285 client.test_down_interface(&intf_name).unwrap();
6286
6287 let mut got_removed = false;
6288
6289 while let Ok(event) = receiver.recv_timeout(timeout) {
6290 if let ServiceEvent::ServiceRemoved(ty_domain, instance) = event {
6291 got_removed = true;
6292 println!("removed: {ty_domain} : {instance}");
6293 break;
6294 }
6295 }
6296 assert!(got_removed, "Should receive ServiceRemoved event");
6297
6298 println!("Bringing up interface {}", &intf_name);
6299 client.test_up_interface(&intf_name).unwrap();
6300 let mut got_data = false;
6301 while let Ok(event) = receiver.recv_timeout(timeout) {
6302 if let ServiceEvent::ServiceResolved(resolved) = event {
6303 got_data = true;
6304 println!("Received ServiceResolved: {:?}", resolved);
6305 break;
6306 }
6307 }
6308 assert!(
6309 got_data,
6310 "Should receive ServiceResolved event after interface is back up"
6311 );
6312
6313 server1.shutdown().unwrap();
6314 client.shutdown().unwrap();
6315 }
6316
6317 #[test]
6318 fn test_cache_only() {
6319 let service_type = "_cache_only._udp.local.";
6321 let instance = "test_instance";
6322 let host_name = "cache_only_host.local.";
6323 let service_ip_addr = my_ip_interfaces(false)
6324 .iter()
6325 .find(|iface| iface.ip().is_ipv4())
6326 .map(|iface| iface.ip())
6327 .unwrap();
6328
6329 let mut my_service = ServiceInfo::new(
6330 service_type,
6331 instance,
6332 host_name,
6333 service_ip_addr,
6334 5023,
6335 None,
6336 )
6337 .unwrap();
6338
6339 let new_ttl = 3; my_service._set_other_ttl(new_ttl);
6341
6342 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6343
6344 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6347 std::thread::sleep(Duration::from_secs(2));
6348
6349 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6351 let result = mdns_server.register(my_service);
6352 assert!(result.is_ok());
6353
6354 let timeout = Duration::from_millis(1500); let mut resolved = false;
6356
6357 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6359 if let ServiceEvent::ServiceResolved(info) = event {
6360 resolved = true;
6361 println!("Resolved a service of {}", &info.get_fullname());
6362 break;
6363 }
6364 }
6365
6366 assert!(resolved);
6367
6368 mdns_server.shutdown().unwrap();
6370 mdns_client.shutdown().unwrap();
6371 }
6372
6373 #[test]
6374 fn test_cache_only_unsolicited() {
6375 let service_type = "_c_unsolicit._udp.local.";
6376 let instance = "test_instance";
6377 let host_name = "c_unsolicit_host.local.";
6378 let service_ip_addr = my_ip_interfaces(false)
6379 .iter()
6380 .find(|iface| iface.ip().is_ipv4())
6381 .map(|iface| iface.ip())
6382 .unwrap();
6383
6384 let my_service = ServiceInfo::new(
6385 service_type,
6386 instance,
6387 host_name,
6388 service_ip_addr,
6389 5023,
6390 None,
6391 )
6392 .unwrap();
6393
6394 let mdns_server = ServiceDaemon::new().expect("Failed to create mdns server");
6396 let result = mdns_server.register(my_service);
6397 assert!(result.is_ok());
6398
6399 let mdns_client = ServiceDaemon::new().expect("Failed to create mdns client");
6400 mdns_client.accept_unsolicited(true).unwrap();
6401
6402 std::thread::sleep(Duration::from_secs(2));
6405 let browse_chan = mdns_client.browse_cache(service_type).unwrap();
6406 let timeout = Duration::from_millis(1500); let mut resolved = false;
6408
6409 while let Ok(event) = browse_chan.recv_timeout(timeout) {
6411 if let ServiceEvent::ServiceResolved(info) = event {
6412 resolved = true;
6413 println!("Resolved a service of {}", &info.get_fullname());
6414 break;
6415 }
6416 }
6417
6418 assert!(resolved);
6419
6420 mdns_server.shutdown().unwrap();
6422 mdns_client.shutdown().unwrap();
6423 }
6424
6425 #[test]
6426 fn test_custom_port_isolation() {
6427 let service_type = "_custom_port._udp.local.";
6432 let instance_custom = "custom_port_instance";
6433 let instance_default = "default_port_instance";
6434 let host_name = "custom_port_host.local.";
6435
6436 let service_ip_addr = my_ip_interfaces(false)
6437 .iter()
6438 .find(|iface| iface.ip().is_ipv4())
6439 .map(|iface| iface.ip())
6440 .expect("Test requires an IPv4 interface");
6441
6442 let service_custom = ServiceInfo::new(
6444 service_type,
6445 instance_custom,
6446 host_name,
6447 service_ip_addr,
6448 8080,
6449 None,
6450 )
6451 .unwrap();
6452
6453 let service_default = ServiceInfo::new(
6455 service_type,
6456 instance_default,
6457 host_name,
6458 service_ip_addr,
6459 8081,
6460 None,
6461 )
6462 .unwrap();
6463
6464 let custom_port = 5454u16;
6466 let server_custom =
6467 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port server");
6468 let client_custom =
6469 ServiceDaemon::new_with_port(custom_port).expect("Failed to create custom port client");
6470
6471 let server_default = ServiceDaemon::new().expect("Failed to create default port server");
6473
6474 server_custom
6476 .register(service_custom.clone())
6477 .expect("Failed to register custom port service");
6478
6479 server_default
6481 .register(service_default.clone())
6482 .expect("Failed to register default port service");
6483
6484 let browse_custom = client_custom
6486 .browse(service_type)
6487 .expect("Failed to browse on custom port");
6488
6489 let timeout = Duration::from_secs(3);
6490 let mut found_custom = false;
6491 let mut found_default_on_custom = false;
6492
6493 while let Ok(event) = browse_custom.recv_timeout(timeout) {
6495 if let ServiceEvent::ServiceResolved(info) = event {
6496 println!(
6497 "Custom port client resolved: {} on port {}",
6498 info.get_fullname(),
6499 info.get_port()
6500 );
6501 if info.get_fullname().starts_with(instance_custom) {
6502 found_custom = true;
6503 assert_eq!(info.get_port(), 8080);
6504 }
6505 if info.get_fullname().starts_with(instance_default) {
6506 found_default_on_custom = true;
6507 }
6508 }
6509 }
6510
6511 assert!(
6512 found_custom,
6513 "Custom port client should find service on custom port"
6514 );
6515 assert!(
6516 !found_default_on_custom,
6517 "Custom port client should NOT find service on default port"
6518 );
6519
6520 let client_default = ServiceDaemon::new().expect("Failed to create default port client");
6523 let browse_default = client_default
6524 .browse(service_type)
6525 .expect("Failed to browse on default port");
6526
6527 let mut found_default = false;
6528 let mut found_custom_on_default = false;
6529
6530 while let Ok(event) = browse_default.recv_timeout(timeout) {
6531 if let ServiceEvent::ServiceResolved(info) = event {
6532 println!(
6533 "Default port client resolved: {} on port {}",
6534 info.get_fullname(),
6535 info.get_port()
6536 );
6537 if info.get_fullname().starts_with(instance_default) {
6538 found_default = true;
6539 assert_eq!(info.get_port(), 8081);
6540 }
6541 if info.get_fullname().starts_with(instance_custom) {
6542 found_custom_on_default = true;
6543 }
6544 }
6545 }
6546
6547 assert!(
6548 found_default,
6549 "Default port client should find service on default port"
6550 );
6551 assert!(
6552 !found_custom_on_default,
6553 "Default port client should NOT find service on custom port"
6554 );
6555
6556 server_custom.shutdown().unwrap();
6558 client_custom.shutdown().unwrap();
6559 server_default.shutdown().unwrap();
6560 client_default.shutdown().unwrap();
6561 }
6562}