-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[MacOS] UDP Multicast: Can't assign requested address on interface 0 (as suggested in the documentation) #123715
Comments
https://stackoverflow.com/questions/65534342/receiving-udp-multicast-on-macos-big-sur suggests that the firewall blocks receiving multicast packets unless "Block all incoming connections" and "stealth mode" are disabled. From a quick search more people seem to be having problems with multicast support on macOS in general. Not just with rust. |
Hello, thank you for the reply. In JVM (Kotlin and Java), I was able to receive multicast packets just fine. ![]() |
Is the java executable signed? If so "Automatically allow downloaded signed software to receive incoming connections" would apply to it, unlike rustc compiled executables, which you probably need to allowlist manually. |
But if that'd be the case, after disabling the firewall I would be able to receive the packets right? However even if disabling the firewall, nothing changes. |
Yeah, it should. Can you check if a C program is able to receive UDP multicast packets as sanity check? |
I will give it my best. I'm not that familiar with C but once i have it written I'll reply to this issue. |
https://gist.github.com/MihaelBercic/557a0386b45e5e912ff493725dfff1f2 This code doesn't work either, can you check if it's the code issue or is it actually not working. |
I don't see anything obviously bad with it, but I'm not all that familiar with the socket api either. In any case for me on linux running that program seems to work as expected when I use iperf to send it multicast packets. |
Does the code also catch packets that are not sent by yourself? Such as tvs, spotify mdns queries and such? |
I looked in wireshark for any multicast packets that are sent my direction by other devices at home, but the only ones I could find were not udp multicast packets and thus wouldn't get caught by this test program. |
Just to add some color to this ticket, here's my program: the python counterpart works just fine: My firewall is off. same code works flawlessly on Debian |
EDIT: this is almost certainly unrelated as it was due to I am running into this as well on macOS. Here is a simple repro: $ cat > example.rs
use std::net::TcpListener;
fn main() {
let _ = TcpListener::bind("127.0.0.1:0").unwrap();
}
$ rustc example.rs && ./example
thread 'main' panicked at example.rs:4:44:
called `Result::unwrap()` on an `Err` value: Os { code: 49, kind: AddrNotAvailable, message: "Can't assign requested address" }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace Nightly has the same bug:
% uname -a
Darwin ok.localdomain 23.4.0 Darwin Kernel Version 23.4.0: Wed Feb 21 21:44:54 PST 2024; root:xnu-10063.101.15~2/RELEASE_ARM64_T6031 arm64
% rustc --version
rustc 1.78.0 (9b00956e5 2024-04-29) |
EDIT: disregard, please see #123715 (comment) Ugh. This is probably a macOS thing:
That said, this code works on macOS, so there is something interesting that Python is doing that seems to allow for things to "just work": |
The python example is not equivalent to others; an empty string implies binding to any interface ( |
EDIT: likely unrelated, see #123715 (comment)
Thanks for the reminder. Indeed. And the C code above does work if we change to |
Same issue on macOS sequoia 15.3 arm64 If binding to 0.0.0.0 or valid adapter, multicast messages are send out. Binding to 0.0.0.0 I can see multicast from the host but not remote. Wireshark is also unable to capture multicast packets. Is Mac always a pain when dealing with the network? import socket
import time
from functools import partial
from contextlib import suppress
from threading import Thread
MCAST_GRP = "239.2.3.1"
MCAST_PORT = 6969
ADAPTER = "192.168.1.195"
# create socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
# reuse addr/port required if other applications binding to same addr/port
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
# binding to "all" interfaces
# most systems (windows, linux) "all" binds to default route interfaces
# binding to adapter does not receive packets
# bind to multicast address on linux
# bind = "0.0.0.0"
bind = ADAPTER
sock.bind((bind, MCAST_PORT))
# required: specify multicast output will throw following error otherwise
# OSError: [Errno 49] Can't assign requested address
# The error occurs on the "sendto" function
# Sendto must try binding to an invalid address if the IP_MULTICAST_IF is not given
sock.setsockopt(
socket.IPPROTO_IP,
socket.IP_MULTICAST_IF,
socket.inet_aton(ADAPTER),
)
# required: send join requst to multicast group
sock.setsockopt(
socket.IPPROTO_IP,
socket.IP_ADD_MEMBERSHIP,
socket.inet_aton(MCAST_GRP) + socket.inet_aton(ADAPTER),
)
# helper sending function
def sender(s_sock, interval=1):
while True:
time.sleep(interval)
data = b"Hello World"
print(f"send: {data}")
s_sock.sendto(data, (MCAST_GRP, MCAST_PORT))
# send mutlicast message
Thread(target=partial(sender, sock), daemon=True).start()
# recv multicast
with suppress(KeyboardInterrupt):
while True:
data, addr = sock.recvfrom(1024)
print(f"recv: {addr} - {data}") |
So far tested on:
The following code
produces the following error:
It is expected for the socket to join the group (in documentation it also says setting interface to 0 allows for the OS to decide on the interface).
However instead of that, on macOS the above error happens. On windows however, it does not and works as expected.
Meta
rustc --version --verbose
:The text was updated successfully, but these errors were encountered: