Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

sendto fails if ip address is "<broadcast>" #540

Open
rlippmann opened this issue May 17, 2023 · 1 comment
Open

sendto fails if ip address is "<broadcast>" #540

rlippmann opened this issue May 17, 2023 · 1 comment

Comments

@rlippmann
Copy link

  • uvloop version: 0.17
  • Python version: 3.10
  • Platform: Ubuntu 22.04, Alpine Linux
  • Can you reproduce the bug with PYTHONASYNCIODEBUG in env?:
  • Does uvloop behave differently from vanilla asyncio? How?: Yes, see below

Some code out there in the wild uses an ip address of "" to indicate a broadcast should be made instead of using 255.255.255.255. i.e.

asyncio.UDPDatagramTransport.sendto(data,"<broadcast>")

This causes sendto() to fail because uvloop tries to resolve this address.

This behavior is all over various packages, i.e.:

./lib/python3.10/site-packages/jaraco/net/wake.py:    s.sendto(magic_packet, ('<broadcast>', 9))
./lib/python3.10/site-packages/elkm1_lib/discovery.py:    BROADCAST_ADDRESS = "<broadcast>"
./lib/python3.10/site-packages/pycomfoconnect/bridge.py:            udpsocket.sendto(b"\x0a\x00", ('<broadcast>', Bridge.PORT))
./lib/python3.10/site-packages/miio/miioprotocol.py:            addr = "<broadcast>"
./lib/python3.10/site-packages/discovery30303/__init__.py:    BROADCAST_ADDRESS = "<broadcast>"
./lib/python3.10/site-packages/nmb/NetBIOSProtocol.py:        # We don't use the transport.write method directly as it keeps raising DeprecationWarning for ip='<broadcast>'
./lib/python3.10/site-packages/nmb/NetBIOSProtocol.py:            ip = '<broadcast>'
./lib/python3.10/site-packages/nmb/NetBIOS.py:            ip = '<broadcast>'
./lib/python3.10/site-packages/flux_led/scanner.py:    BROADCAST_ADDRESS = "<broadcast>"
./lib/python3.10/site-packages/aiosenseme/discovery.py:            self.transport.sendto(data, ("<broadcast>", PORT))
./lib/python3.10/site-packages/pyric/pyw.py:     set nic's ip4 netmask (ifconfig <card.dev> broadcast <broadcast>
./lib/python3.10/site-packages/unifi_discovery/__init__.py:            address = "<broadcast>"
./lib/python3.10/site-packages/roonapi/discovery.py:            sock.sendto(msg, ("<broadcast>", SOOD_PORT))
./lib/python3.10/site-packages/pybravia/client.py:            sock.sendto(packet, ("<broadcast>", 9))
./lib/python3.10/site-packages/roombapy/discovery.py:    udp_address = "<broadcast>"

so this behavior breaks a lot of things.

It would be a trivial change to implement in uvloop, just check if address == "<broadcast>" and replace it with 255.255.255.255

@rlippmann
Copy link
Author

I double checked, and it is valid python:

link

For IPv4 addresses, two special forms are accepted instead of a host address: '' represents INADDR_ANY, which is used to bind to all interfaces, and the string '<broadcast>' represents INADDR_BROADCAST. This behavior is not compatible with IPv6, therefore, you may want to avoid these if you intend to support IPv6 with your Python programs.

It looks like CPython implements it in socketmodule.c:setipaddress()

source

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant