Skip to content

Commit

Permalink
Handle socket.IPV6_MULTICAST_IF failing to be set
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Jan 24, 2025
1 parent ba4c943 commit 2596903
Showing 1 changed file with 37 additions and 34 deletions.
71 changes: 37 additions & 34 deletions wsdiscovery/threaded.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,15 @@ def _createMulticastOutSocket(self, addr, ttl):
else:
iface = int(addr.scope_id)

sock.setsockopt(ip_proto, self._get_multicast(), iface)
try:
sock.setsockopt(ip_proto, self._get_multicast(), iface)
except OSError as e:
logger.warning(
"Interface for %s does not support "
"multicast flags or is not UP: OSError %s",
addr,
e
)

return sock

Expand All @@ -142,7 +150,7 @@ def addSourceAddr(self, addr):
try:
self._multiInSocket.setsockopt(self._get_ip_proto(), self._get_ip_join(), self._makeMreq(addr))
except socket.error as e:
logger.debug(f"Interface has more than 1 address: {e}")
logger.warning(f"Interface has more than 1 address: {e}")

sock = self._createMulticastOutSocket(addr, self._observer.ttl)
self._multiOutUniInSockets[addr] = sock
Expand All @@ -152,7 +160,7 @@ def removeSourceAddr(self, addr):
try:
self._multiInSocket.setsockopt(self._get_ip_proto(), self._get_ip_leave(), self._makeMreq(addr))
except socket.error as e:
logger.debug(f"Interface has more than 1 address: {e}")
logger.warning(f"Interface has more than 1 address: {e}")

sock = self._multiOutUniInSockets[addr]
self._selector.unregister(sock)
Expand Down Expand Up @@ -388,36 +396,33 @@ def _startThreads(self):
return

self._networkingThread_v4 = NetworkingThreadIPv4(self)
self._networkingThread_v6 = NetworkingThreadIPv6(self)
self._networkingThread_v4.start()
self._addrsMonitorThread_v4 = AddressMonitorThread(self, socket.AF_INET)
self._addrsMonitorThread_v4.start()
self._networkingThread_v6.start()
logger.debug("networking threads started")

try:
self._networkingThread_v6 = NetworkingThreadIPv6(self)
self._networkingThread_v6.start()
self._addrsMonitorThread_v6 = AddressMonitorThread(self, socket.AF_INET6)
self._addrsMonitorThread_v6.start()
except OSError as e:
logger.debug("IPv6 not supported: %s", e)
self._networkingThread_v6 = None
self._addrsMonitorThread_v6 = None
self._addrsMonitorThread_v4 = AddressMonitorThread(self, socket.AF_INET)
self._addrsMonitorThread_v6 = AddressMonitorThread(self, socket.AF_INET6)
self._addrsMonitorThread_v4.start()
self._addrsMonitorThread_v6.start()
logger.debug("address monitoring threads started")

def _stopThreads(self):
if self._networkingThread_v4 is not None:
self._networkingThread_v4.schedule_stop()
self._addrsMonitorThread_v4.schedule_stop()
self._networkingThread_v4.join()
self._addrsMonitorThread_v4.join()
self._networkingThread_v4 = None

if self._networkingThread_v6 is not None:
self._networkingThread_v6.schedule_stop()
self._addrsMonitorThread_v6.schedule_stop()
self._networkingThread_v6.join()
self._addrsMonitorThread_v6.join()
self._networkingThread_v6 = None
if self._networkingThread_v4 is None:
return

self._networkingThread_v4.schedule_stop()
self._addrsMonitorThread_v4.schedule_stop()
self._networkingThread_v6.schedule_stop()
self._addrsMonitorThread_v6.schedule_stop()

self._networkingThread_v4.join()
self._addrsMonitorThread_v4.join()
self._networkingThread_v6.join()
self._addrsMonitorThread_v6.join()

self._networkingThread_v4 = None
self._networkingThread_v6 = None

def start(self):
"""start networking - should be called before using other methods"""
Expand All @@ -433,24 +438,23 @@ def addSourceAddr(self, addr):
version = ipaddress.ip_address(addr).version
if version == 4:
self._networkingThread_v4.addSourceAddr(addr)
elif version == 6 and self._networkingThread_v6 is not None:
elif version == 6:
self._networkingThread_v6.addSourceAddr(addr)

def removeSourceAddr(self, addr):
version = ipaddress.ip_address(addr).version
if version == 4:
self._networkingThread_v4.removeSourceAddr(addr)
elif version == 6 and self._networkingThread_v6 is not None:
elif version == 6:
self._networkingThread_v6.removeSourceAddr(addr)

def sendUnicastMessage(self, env, host, port, initialDelay=0,
unicast_num=UNICAST_UDP_REPEAT):
"handle unicast message sending"
self._networkingThread_v4.addUnicastMessage(env, host, port,
initialDelay, unicast_num)
if self._networkingThread_v6 is not None:
self._networkingThread_v6.addUnicastMessage(env, host, port,
initialDelay, unicast_num)
self._networkingThread_v6.addUnicastMessage(env, host, port,
initialDelay, unicast_num)

def sendMulticastMessage(self, env, initialDelay=0,
multicast_num=MULTICAST_UDP_REPEAT):
Expand All @@ -460,8 +464,7 @@ def sendMulticastMessage(self, env, initialDelay=0,
MULTICAST_PORT,
initialDelay,
multicast_num)
if self._networkingThread_v6 is not None:
self._networkingThread_v6.addMulticastMessage(env,
self._networkingThread_v6.addMulticastMessage(env,
MULTICAST_IPV6_ADDRESS,
MULTICAST_PORT,
initialDelay,
Expand Down

0 comments on commit 2596903

Please sign in to comment.