christgau / wsdd

A Web Service Discovery host daemon.
MIT License
808 stars 97 forks source link

"OSError: illegal IP address string passed to inet_pton" for IPv6 addresses with scope IDs (link-local addresses with "%") #184

Closed brunokc closed 7 months ago

brunokc commented 8 months ago

The problem happens in line 96:

        self._raw_address = raw if isinstance(raw, bytes) else socket.inet_pton(family, raw)

with addresses of the form fe80::1c93:15b1:b6e3:91a4%eth1

I get lots of errors from wsdd like these (while running as a deamon under systemd):

OSError: illegal IP address string passed to inet_pton
Oct 13 18:32:50 sun wsdd[30824]: ERROR: Exception in callback MulticastHandler.read_socket(<socket.socke..., 3702, 0, 3)>)
Oct 13 18:32:50 sun wsdd[30824]: handle: <Handle MulticastHandler.read_socket(<socket.socke..., 3702, 0, 3)>)>
Oct 13 18:32:50 sun wsdd[30824]: Traceback (most recent call last):
Oct 13 18:32:50 sun wsdd[30824]:   File "/usr/lib64/python3.6/asyncio/events.py", line 145, in _run
Oct 13 18:32:50 sun wsdd[30824]:   File "/usr/local/sbin/wsdd", line 329, in read_socket
Oct 13 18:32:50 sun wsdd[30824]:   File "/usr/local/sbin/wsdd", line 154, in __init__
Oct 13 18:32:50 sun wsdd[30824]:   File "/usr/local/sbin/wsdd", line 96, in __init__

The fix seems to be to simply drop the zone id from the link-local IPv6 address before passing it to inet_pton as proposed below:

         if isinstance(raw, bytes):
             self._raw_address = raw
         else:
             zone_id_idx = raw.rfind("%")
             if zone_id_idx >= 0:
                 raw = raw[:zone_id_idx]
             self._raw_address = socket.inet_pton(family, raw)