Skip to content

Commit

Permalink
[mdns] Fix multicast routing error on esp32 (and likely other platforms)
Browse files Browse the repository at this point in the history
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 project-chip#100
  • Loading branch information
jasta committed Oct 4, 2023
1 parent e39fd18 commit fda6574
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 30 deletions.
62 changes: 35 additions & 27 deletions rs-matter/src/mdns/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -217,40 +219,46 @@ 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;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion rs-matter/src/transport/exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ impl ExchangeCtx {
} else {
0
},
session_id: session_id.clone(),
session_id,
},
role: if reply_to.is_some() {
Role::Responder
Expand Down
4 changes: 2 additions & 2 deletions rs-matter/src/transport/network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit fda6574

Please sign in to comment.