Open andrewyager opened 7 months ago
Implementing a bind_interface
parameter for sACNreceiver
should not be any problem.
However, did you encounter any issues on Linux when trying to receive multicast sACN packets? #42 suggests that it should now be possible by providing an IP (maybe even 0.0.0.0
).
Is this potentially related to #45 ?
I think this may in fact be true; let me keep testing!
Closing issue as this seems to have been a product of #45
Coming back to this issue and re-opening it as I've now had to properly triage what is causing it.
I've done a fresh install of Ubuntu 22.04 with Python 3.10.2 and 5.15.0-112-generic.
The host has two IP interfaces:
ens3: 192.168.1.211/24 ens4: 192.168.5.17/24
I have started sACNView on another host and told it to broadcast onto Universe 1 on the the ens4 network.
I confirmed that tcpDump can see the packets on the ens4 network.
The following does not receive any incoming packets on the ens4 interface as far as the code is concerned.
So having tested that, I checked out a local copy of the sacn package and started tinkering.
The following change does, however, make everything work:
diff --git a/sacn/receiving/receiver_socket_udp.py b/sacn/receiving/receiver_socket_udp.py
index ab1fad0..d3935c4 100644
--- a/sacn/receiving/receiver_socket_udp.py
+++ b/sacn/receiving/receiver_socket_udp.py
@@ -26,7 +26,7 @@ class ReceiverSocketUDP(ReceiverSocketBase):
self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
except socket.error: # Not all systems support multiple sockets on the same port and interface
pass
- self._socket.bind((self._bind_address, self._bind_port))
+ self._socket.bind(('', self._bind_port))
self._logger.info(f'Bind receiver socket to IP: {self._bind_address} port: {self._bind_port}')
def start(self):
After making this change, I checked the following:
The following receives packets (as expected):
The following does not receive packets (probably as expected?)
Changing the source to be on the other interface (facing 192.168.1.211) will cause the host to receive packets in the second scenario (because ens3 is the first interface on the host).
This also reflects the multicast membership joins.
Interestingly, in all cases, specifying the correct interface always resulted in the ip maddr show
command showing that the group memberships were correct; but obviously something about the 'bind' operation meant that it would not pick up the packets when they came in on the second interface.
As the notes indicate, the interface bind on Linux doesn't work, particularly when we are dealing with multicast traffic. There are a range of reasons for this, but the socket implementation doesn't really lend itself to being used in this way.
The fix for this is to do something like:
It would be nice to simply extend sACNreceiver to allow this to be set without requiring a bit of internal digging to find that interface name. This is obviously a Linux only implementation; and I'm not sure that it is quite the same to implement in Windows - I have specifically not tested this in this environment.
I have tested this in Python 3.9+ on a range of 5 series kernels without issue.