trying to fix windows multicast

This commit is contained in:
Igor Katson 2024-09-15 22:28:43 +01:00
parent b3263c24d3
commit 8d8d5491f9
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5
3 changed files with 38 additions and 16 deletions

1
Cargo.lock generated
View file

@ -2710,6 +2710,7 @@ dependencies = [
"tracing-subscriber", "tracing-subscriber",
"url", "url",
"uuid", "uuid",
"winapi",
] ]
[[package]] [[package]]

View file

@ -41,6 +41,9 @@ network-interface = "2.0.0"
futures = "0.3.30" futures = "0.3.30"
libc = "0.2.158" libc = "0.2.158"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.9", features = ["winsock2"] }
[dev-dependencies] [dev-dependencies]
tracing-subscriber = "0.3.18" tracing-subscriber = "0.3.18"
tower-http = { version = "0.5", features = ["trace"] } tower-http = { version = "0.5", features = ["trace"] }

View file

@ -1,7 +1,6 @@
use std::{ use std::{
collections::HashSet, collections::HashSet,
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
os::fd::{AsFd, AsRawFd},
time::Duration, time::Duration,
}; };
@ -217,24 +216,43 @@ struct MulticastOpts {
addr: SocketAddr, addr: SocketAddr,
} }
fn set_mcast_if(sock: &UdpSocket, local_ip: Ipv4Addr) -> std::io::Result<()> { fn set_mcast_if(sock: &UdpSocket, local_ip: Ipv4Addr) -> anyhow::Result<()> {
let addr = libc::in_addr { // in_addr is the same on unix and windows and contains just the 4 bytes of IPv4 in network
s_addr: u32::from_ne_bytes(local_ip.octets()), // byte order.
}; let addr = u32::from_ne_bytes(local_ip.octets());
const SZ: usize = std::mem::size_of::<libc::in_addr>(); let sz: usize = std::mem::size_of_val(&addr);
trace!(addr = %local_ip, "setting IP_MULTICAST_IF"); trace!(addr = %local_ip, "setting IP_MULTICAST_IF");
let ret = unsafe {
libc::setsockopt( let ret: i32;
sock.as_fd().as_raw_fd(), #[cfg(target_os = "windows")]
libc::IPPROTO_IP, {
libc::IP_MULTICAST_IF, use std::os::windows::io::AsRawSocket;
&addr as *const _ as _, ret = unsafe {
SZ as u32, winapi::um::winsock2::setsockopt(
) sock.as_raw_socket().try_into()?,
}; winapi::shared::ws2def::IPPROTO_IP,
winapi::shared::ws2ipdef::IP_MULTICAST_IF,
&addr as *const _ as _,
sz.try_into()?,
)
};
}
#[cfg(not(target_os = "windows"))]
{
use std::os::fd::{AsFd, AsRawFd};
ret = unsafe {
libc::setsockopt(
sock.as_fd().as_raw_fd(),
libc::IPPROTO_IP,
libc::IP_MULTICAST_IF,
&addr as *const _ as _,
sz.try_into()?,
)
};
}
if ret < 0 { if ret < 0 {
return Err(std::io::Error::last_os_error()); return Err(std::io::Error::last_os_error().into());
} }
Ok(()) Ok(())
} }