mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-24 18:51:11 +00:00
ptp: use ip_mreq instead of ip_mreqn for macOS
To join a multicast the macOS still uses the interface address from the ip_mreq instead of the ip_mreqn unlike other Linux systems. So add a new conditional block for macOS to use ip_mreq for IP_ADD_MEMBERSHIP and ip_mreqn for IP_MULTICAST_IF This is similar to the fix in the glib for multicast join/leave operation on macOS https://gitlab.gnome.org/GNOME/glib/-/merge_requests/4333 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7851>
This commit is contained in:
parent
e57bd3b0dc
commit
36d8243397
2 changed files with 75 additions and 8 deletions
|
@ -376,6 +376,15 @@ pub mod unix {
|
|||
pub imr_ifindex: c_int,
|
||||
}
|
||||
|
||||
// macOS uses ip_mreq instead of ip_mreqn in its latest version of the MAC Kernel for IP_ADD_MEMBERSHIP
|
||||
#[cfg(target_os = "macos")]
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ip_mreq {
|
||||
pub imr_multiaddr: in_addr,
|
||||
pub imr_address: in_addr,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||
#[repr(C)]
|
||||
pub struct ifaddrs {
|
||||
|
|
|
@ -376,7 +376,7 @@ mod imp {
|
|||
addr: &Ipv4Addr,
|
||||
iface: &InterfaceInfo,
|
||||
) -> Result<(), Error> {
|
||||
#[cfg(not(any(target_os = "solaris", target_os = "illumos")))]
|
||||
#[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "macos")))]
|
||||
{
|
||||
let mreqn = ip_mreqn {
|
||||
imr_multiaddr: in_addr {
|
||||
|
@ -408,12 +408,7 @@ mod imp {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "netbsd",
|
||||
target_os = "macos"
|
||||
)))]
|
||||
#[cfg(not(any(target_os = "openbsd", target_os = "dragonfly", target_os = "netbsd")))]
|
||||
{
|
||||
let mreqn = ip_mreqn {
|
||||
imr_multiaddr: in_addr {
|
||||
|
@ -445,7 +440,7 @@ mod imp {
|
|||
}
|
||||
}
|
||||
}
|
||||
#[cfg(any(target_os = "openbsd", target_os = "dragonfly", target_os = "macos"))]
|
||||
#[cfg(any(target_os = "openbsd", target_os = "dragonfly"))]
|
||||
{
|
||||
let addr = in_addr {
|
||||
s_addr: u32::from_ne_bytes(iface.ip_addr.octets()),
|
||||
|
@ -534,6 +529,69 @@ mod imp {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let mreq = ip_mreq {
|
||||
imr_multiaddr: in_addr {
|
||||
s_addr: u32::from_ne_bytes(addr.octets()),
|
||||
},
|
||||
imr_address: in_addr {
|
||||
s_addr: u32::from_ne_bytes(iface.ip_addr.octets()),
|
||||
},
|
||||
};
|
||||
|
||||
let mreqn = ip_mreqn {
|
||||
imr_multiaddr: in_addr {
|
||||
s_addr: u32::from_ne_bytes(Ipv4Addr::UNSPECIFIED.octets()),
|
||||
},
|
||||
imr_address: in_addr {
|
||||
s_addr: u32::from_ne_bytes(Ipv4Addr::UNSPECIFIED.octets()),
|
||||
},
|
||||
imr_ifindex: iface.index as _,
|
||||
};
|
||||
|
||||
// SAFETY: Requires a valid ip_mreq struct to be passed together with its size for checking
|
||||
// validity. On errors a negative integer is returned.
|
||||
unsafe {
|
||||
if setsockopt(
|
||||
socket.as_raw_fd(),
|
||||
IPPROTO_IP,
|
||||
IP_ADD_MEMBERSHIP,
|
||||
&mreq as *const _ as *const _,
|
||||
mem::size_of_val(&mreq) as _,
|
||||
) < 0
|
||||
{
|
||||
bail!(
|
||||
source: io::Error::last_os_error(),
|
||||
"Failed joining multicast group for interface {}",
|
||||
iface.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: Requires a valid ip_mreqn struct to be passed together
|
||||
// with its size for checking which of the two it is. On errors a negative
|
||||
// integer is returned.
|
||||
unsafe {
|
||||
if setsockopt(
|
||||
socket.as_raw_fd(),
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_IF,
|
||||
&mreqn as *const _ as *const _,
|
||||
mem::size_of_val(&mreqn) as _,
|
||||
) < 0
|
||||
{
|
||||
bail!(
|
||||
source: io::Error::last_os_error(),
|
||||
"Failed joining multicast group for interface {}",
|
||||
iface.name,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Allow multiple sockets to bind to the same address / port.
|
||||
|
|
Loading…
Reference in a new issue