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