From d84402f5713ff5f92cf38314af643d39552311a1 Mon Sep 17 00:00:00 2001 From: Josh Guilfoyle Date: Tue, 3 Oct 2023 16:29:13 -0700 Subject: [PATCH] [mdns] Fix multicast routing error on esp32 (and likely other platforms) According to the RFC (https://datatracker.ietf.org/doc/html/rfc2553#section-3.3), it is necessary to disambiguate link-local addresses with the interface index (in the scope_id field). Lacking this field, newer versions of lwip that support proper IPv6 scopes will yield EHOSTUNREACH (Host unreachable). Other implementations like on Linux and OS X will likely be affected by the lack of this field for more complex networking setups. Fixes #100 Run cargo fmt again Run cargo clippy again Revert "Run cargo clippy again" This reverts commit e3bba1f6367172d9ecd07c8c8fb7263cda40e8f6. --- rs-matter/src/mdns/builtin.rs | 59 ++++++++++++++++-------------- rs-matter/src/transport/network.rs | 4 +- 2 files changed, 34 insertions(+), 29 deletions(-) diff --git a/rs-matter/src/mdns/builtin.rs b/rs-matter/src/mdns/builtin.rs index 5ca8676..f329ef2 100644 --- a/rs-matter/src/mdns/builtin.rs +++ b/rs-matter/src/mdns/builtin.rs @@ -8,7 +8,9 @@ use log::info; use crate::data_model::cluster_basic_information::BasicInfoConfig; use crate::error::{Error, ErrorCode}; -use crate::transport::network::{Address, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use crate::transport::network::{ + Address, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, +}; use crate::transport::pipe::{Chunk, Pipe}; use crate::utils::select::{EitherUnwrap, Notification}; @@ -217,40 +219,43 @@ impl<'a> MdnsService<'a> { .await; for addr in [ - IpAddr::V4(IP_BROADCAST_ADDR), - IpAddr::V6(IPV6_BROADCAST_ADDR), - ] { - if self.interface.is_some() || addr == IpAddr::V4(IP_BROADCAST_ADDR) { - loop { - let sent = { - let mut data = tx_pipe.data.lock().await; + Some(SocketAddr::V4(SocketAddrV4::new(IP_BROADCAST_ADDR, PORT))), + self.interface.map(|interface| { + SocketAddr::V6(SocketAddrV6::new(IPV6_BROADCAST_ADDR, PORT, 0, interface)) + }), + ] + .into_iter() + .flatten() + { + loop { + let sent = { + let mut data = tx_pipe.data.lock().await; - if data.chunk.is_none() { - let len = self.host.broadcast(self, data.buf, 60)?; + if data.chunk.is_none() { + let len = self.host.broadcast(self, data.buf, 60)?; - if len > 0 { - info!("Broadcasting mDNS entry to {}:{}", addr, PORT); + if len > 0 { + info!("Broadcasting mDNS entry to {addr}"); - data.chunk = Some(Chunk { - start: 0, - end: len, - addr: Address::Udp(SocketAddr::new(addr, PORT)), - }); + data.chunk = Some(Chunk { + start: 0, + end: len, + addr: Address::Udp(addr), + }); - tx_pipe.data_supplied_notification.signal(()); - } - - true - } else { - false + tx_pipe.data_supplied_notification.signal(()); } - }; - if sent { - break; + true } else { - tx_pipe.data_consumed_notification.wait().await; + false } + }; + + if sent { + break; + } else { + tx_pipe.data_consumed_notification.wait().await; } } } diff --git a/rs-matter/src/transport/network.rs b/rs-matter/src/transport/network.rs index 7a2ca9f..0aa4413 100644 --- a/rs-matter/src/transport/network.rs +++ b/rs-matter/src/transport/network.rs @@ -17,9 +17,9 @@ use core::fmt::{Debug, Display}; #[cfg(not(feature = "std"))] -pub use no_std_net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +pub use no_std_net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; #[cfg(feature = "std")] -pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +pub use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; #[derive(Eq, PartialEq, Copy, Clone)] pub enum Address {