I'm trying to implement SSDP listener in Rust: create a socket that receives UDP datagrams sent to 239.255.255.250:1900 multicast. I don't really want to reinvent the wheel but I haven't found any crate that would not only query using M-SEARCH, but also receive NOTIFY events.
I have the following socket that works fine and receives all the data I need, as long as I have only one process running:
pub const SSDP_IP_ADDR: Ipv4Addr = Ipv4Addr::new(239, 255, 255, 250);
fn new_socket() -> Result<UdpSocket, Box<dyn std::error::Error>> {
let local_addr = Ipv4Addr::new(0, 0, 0,0);
let bind_addr = SocketAddrV4::new(local_addr, 1900);
// I'm using socket2's Socket here
let socket = Socket::new(
Domain::ipv4(),
Type::dgram(),
Some(Protocol::udp())
)?;
socket.set_broadcast(true)?;
socket.set_reuse_address(true)?;
socket.set_reuse_port(true)?; // required on macOS and iOS
socket.join_multicast_v4(&SSDP_IP_ADDR, &local_addr)?;
socket.bind(&bind_addr.into())?;
Ok(socket.into_udp_socket())
}
However, when I have more than one process running, datagrams are not sent to all processes/sockets. Instead, they seem to be distributed somewhat randomly, or with a preference to the socket that was bound first.
Is there any way to force macOS/iOS to send all datagrams to all processes/sockets bound to this multicast group?