Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions protocols/mdns/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## 0.46.0

- Issue a warning if configured for IPv6 on Apple platforms and a more explanatory error when
binding to that port fails. See [PR 5527](https://github.com/libp2p/rust-libp2p/pull/5526).

<!-- Update to libp2p-swarm v0.45.0 -->
## 0.45.2

Expand Down
26 changes: 25 additions & 1 deletion protocols/mdns/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,23 @@ where
}
self.closest_expiration = Some(P::Timer::at(now));
}

#[cfg(not(target_vendor = "apple"))]
fn apple_warning(&self) {}

#[cfg(target_vendor = "apple")]
fn apple_warning(&self) {
static APPLE_WARNING: std::sync::atomic::AtomicBool =
std::sync::atomic::AtomicBool::new(false);
let is_ipv6 = self.config.enable_ipv6;
if APPLE_WARNING.load(std::sync::atomic::Ordering::Relaxed) {
return;
}
APPLE_WARNING.store(true, std::sync::atomic::Ordering::Relaxed);
if is_ipv6 {
tracing::warn!("You are using IPv6 with mDNS on an Apple device. This may fail due to the mDNSResponder, a system service, using that port. For more infos: `man mdnsresponder`");
}
}
}

impl<P> NetworkBehaviour for Behaviour<P>
Expand Down Expand Up @@ -290,6 +307,8 @@ where
&mut self,
cx: &mut Context<'_>,
) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
self.apple_warning();

// Poll ifwatch.
while let Poll::Ready(Some(event)) = Pin::new(&mut self.if_watch).poll_next(cx) {
match event {
Expand All @@ -315,7 +334,12 @@ where
e.insert(P::spawn(iface_state));
}
Err(err) => {
tracing::error!("failed to create `InterfaceState`: {}", err)
const IS_APPLE: bool = cfg!(target_vendor = "apple");
if IS_APPLE && addr.is_ipv6() {
tracing::error!("failed to create `InterfaceState`: {}. This is likely because the mDNSResponder, a system service, is using that port. For more infos: `man mdnsresponder`", err)
} else {
tracing::error!("failed to create `InterfaceState`: {}", err)
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions protocols/mdns/tests/use-async-std.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ async fn test_discovery_async_std_ipv4() {
run_discovery_test(Config::default()).await
}

// This test (typically) doesn't work on macOS because that port and address are already used execlusively by
// mdnsResponder, which is a system service.
#[cfg_attr(target_vendor = "apple", ignore)]
#[async_std::test]
async fn test_discovery_async_std_ipv6() {
let _ = tracing_subscriber::fmt()
Expand Down
1 change: 1 addition & 0 deletions protocols/mdns/tests/use-tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ async fn test_discovery_tokio_ipv4() {
run_discovery_test(Config::default()).await
}

#[cfg_attr(target_vendor = "apple", ignore)]
#[tokio::test]
async fn test_discovery_tokio_ipv6() {
let _ = tracing_subscriber::fmt()
Expand Down