Skip to content

WinError 10022 for create_datagram_endpoint with local_addr=None. #119711

Open
@lschoe

Description

@lschoe

Bug report

Bug description:

A problem occurs with the Windows proactor event loop when creating a datagram endpoint with local_addr=None. The problem does not occur with the selector event loop (either on Windows or Linux).

import socket
import asyncio

class MyDatagramProto(asyncio.DatagramProtocol):

   def error_received(self, exc):
       raise exc


asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
loop = asyncio.new_event_loop()
coro = loop.create_datagram_endpoint(MyDatagramProto, local_addr=None, family=socket.AF_INET)
loop.run_until_complete(coro)

print('No problem with selector loop.')
print()

asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
loop = asyncio.new_event_loop()
coro = loop.create_datagram_endpoint(MyDatagramProto, local_addr=None, family=socket.AF_INET)
loop.run_until_complete(coro)

print()
print('We got error 10022 with proactor loop.')

gives as output

No problem with selector loop.

Exception in callback _ProactorDatagramTransport._loop_reading()
handle: <Handle _ProactorDatagramTransport._loop_reading()>
Traceback (most recent call last):
  File "C:\Users\Berry\AppData\Local\Programs\Python\Python313\Lib\asyncio\events.py", line 89, in _run
    self._context.run(self._callback, *self._args)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Berry\AppData\Local\Programs\Python\Python313\Lib\asyncio\proactor_events.py", line 577, in _loop_reading
    self._protocol.error_received(exc)
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^
  File "C:\Users\Berry\Desktop\scratch\bugasynciolocaddrNone.py", line 7, in error_received
    raise exc
  File "C:\Users\Berry\AppData\Local\Programs\Python\Python313\Lib\asyncio\proactor_events.py", line 574, in _loop_reading
    self._read_fut = self._loop._proactor.recvfrom(self._sock,
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
                                                   self.max_size)
                                                   ^^^^^^^^^^^^^^
  File "C:\Users\Berry\AppData\Local\Programs\Python\Python313\Lib\asyncio\windows_events.py", line 513, in recvfrom
    ov.WSARecvFrom(conn.fileno(), nbytes, flags)
    ~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
OSError: [WinError 10022] An invalid argument was supplied

We got error 10022 with proactor loop.

The problem happens because the socket conn is not bound when WSARecvFrom is called. The bind() call is skipped because the local address was None, see:

if local_addr:
sock.bind(local_address)

The code above is a stripped down version of the following uvloop test case:
https://github.com/MagicStack/uvloop/blob/6c770dc3fbdd281d15c2ad46588c139696f9269c/tests/test_udp.py#L141-L160
This test passes on Linux both with the uvloop and with the asyncio (selector) loop.

CPython versions tested on:

3.8, 3.9, 3.10, 3.11, 3.12, 3.13

Operating systems tested on:

Windows

Metadata

Metadata

Assignees

No one assigned

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions