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,
|
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"))]
|
#[cfg(any(target_os = "solaris", target_os = "illumos"))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ifaddrs {
|
pub struct ifaddrs {
|
||||||
|
|
|
@ -376,7 +376,7 @@ mod imp {
|
||||||
addr: &Ipv4Addr,
|
addr: &Ipv4Addr,
|
||||||
iface: &InterfaceInfo,
|
iface: &InterfaceInfo,
|
||||||
) -> Result<(), Error> {
|
) -> 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 {
|
let mreqn = ip_mreqn {
|
||||||
imr_multiaddr: in_addr {
|
imr_multiaddr: in_addr {
|
||||||
|
@ -408,12 +408,7 @@ mod imp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(
|
#[cfg(not(any(target_os = "openbsd", target_os = "dragonfly", target_os = "netbsd")))]
|
||||||
target_os = "openbsd",
|
|
||||||
target_os = "dragonfly",
|
|
||||||
target_os = "netbsd",
|
|
||||||
target_os = "macos"
|
|
||||||
)))]
|
|
||||||
{
|
{
|
||||||
let mreqn = ip_mreqn {
|
let mreqn = ip_mreqn {
|
||||||
imr_multiaddr: in_addr {
|
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 {
|
let addr = in_addr {
|
||||||
s_addr: u32::from_ne_bytes(iface.ip_addr.octets()),
|
s_addr: u32::from_ne_bytes(iface.ip_addr.octets()),
|
||||||
|
@ -534,6 +529,69 @@ mod imp {
|
||||||
|
|
||||||
Ok(())
|
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.
|
/// Allow multiple sockets to bind to the same address / port.
|
||||||
|
|
Loading…
Reference in a new issue