mirror of https://github.com/MagicStack/uvloop.git
parent
9e017e6ee9
commit
506a2aa1eb
|
@ -328,6 +328,47 @@ class _TestUDP:
|
|||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
|
||||
def _skip_create_datagram_endpoint_reuse_addr(self):
|
||||
if self.implementation == 'asyncio':
|
||||
if sys.version_info[:2] >= (3, 11):
|
||||
raise unittest.SkipTest()
|
||||
if (3, 8, 0) <= sys.version_info < (3, 8, 1):
|
||||
raise unittest.SkipTest()
|
||||
if (3, 7, 0) <= sys.version_info < (3, 7, 6):
|
||||
raise unittest.SkipTest()
|
||||
if sys.version_info < (3, 6, 10):
|
||||
raise unittest.SkipTest()
|
||||
|
||||
def test_create_datagram_endpoint_reuse_address_error(self):
|
||||
# bpo-37228: Ensure that explicit passing of `reuse_address=True`
|
||||
# raises an error, as it is not safe to use SO_REUSEADDR when using UDP
|
||||
|
||||
self._skip_create_datagram_endpoint_reuse_addr()
|
||||
|
||||
coro = self.loop.create_datagram_endpoint(
|
||||
lambda: MyDatagramProto(loop=self.loop),
|
||||
local_addr=('127.0.0.1', 0),
|
||||
reuse_address=True)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
self.loop.run_until_complete(coro)
|
||||
|
||||
def test_create_datagram_endpoint_reuse_address_warning(self):
|
||||
# bpo-37228: Deprecate *reuse_address* parameter
|
||||
|
||||
self._skip_create_datagram_endpoint_reuse_addr()
|
||||
|
||||
coro = self.loop.create_datagram_endpoint(
|
||||
lambda: MyDatagramProto(loop=self.loop),
|
||||
local_addr=('127.0.0.1', 0),
|
||||
reuse_address=False)
|
||||
|
||||
with self.assertWarns(DeprecationWarning):
|
||||
tr, pr = self.loop.run_until_complete(coro)
|
||||
|
||||
tr.close()
|
||||
self.loop.run_until_complete(pr.done)
|
||||
|
||||
|
||||
class Test_UV_UDP(_TestUDP, tb.UVTestCase):
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ cdef class UDPTransport(UVBaseTransport):
|
|||
|
||||
cdef _connect(self, system.sockaddr* addr, size_t addr_len)
|
||||
|
||||
cdef _bind(self, system.sockaddr* addr, bint reuse_addr)
|
||||
cdef _bind(self, system.sockaddr* addr)
|
||||
cdef open(self, int family, int sockfd)
|
||||
cdef _set_broadcast(self, bint on)
|
||||
|
||||
|
|
|
@ -104,16 +104,13 @@ cdef class UDPTransport(UVBaseTransport):
|
|||
exc = convert_error(err)
|
||||
raise exc
|
||||
|
||||
cdef _bind(self, system.sockaddr* addr, bint reuse_addr):
|
||||
cdef _bind(self, system.sockaddr* addr):
|
||||
cdef:
|
||||
int err
|
||||
int flags = 0
|
||||
|
||||
self._ensure_alive()
|
||||
|
||||
if reuse_addr:
|
||||
flags |= uv.UV_UDP_REUSEADDR
|
||||
|
||||
err = uv.uv_udp_bind(<uv.uv_udp_t*>self._handle, addr, flags)
|
||||
if err < 0:
|
||||
exc = convert_error(err)
|
||||
|
|
|
@ -199,8 +199,7 @@ cdef extern from "uv.h" nogil:
|
|||
|
||||
ctypedef enum uv_udp_flags:
|
||||
UV_UDP_IPV6ONLY = 1,
|
||||
UV_UDP_PARTIAL = 2,
|
||||
UV_UDP_REUSEADDR = 4
|
||||
UV_UDP_PARTIAL = 2
|
||||
|
||||
ctypedef enum uv_membership:
|
||||
UV_LEAVE_GROUP = 0,
|
||||
|
|
|
@ -90,6 +90,11 @@ cdef inline socket_dec_io_ref(sock):
|
|||
sock._decref_socketios()
|
||||
|
||||
|
||||
# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s
|
||||
# *reuse_address* parameter
|
||||
_unset = object()
|
||||
|
||||
|
||||
@cython.no_gc_clear
|
||||
cdef class Loop:
|
||||
def __cinit__(self):
|
||||
|
@ -2924,7 +2929,7 @@ cdef class Loop:
|
|||
async def create_datagram_endpoint(self, protocol_factory,
|
||||
local_addr=None, remote_addr=None, *,
|
||||
family=0, proto=0, flags=0,
|
||||
reuse_address=None, reuse_port=None,
|
||||
reuse_address=_unset, reuse_port=None,
|
||||
allow_broadcast=None, sock=None):
|
||||
"""A coroutine which creates a datagram endpoint.
|
||||
|
||||
|
@ -2936,11 +2941,6 @@ cdef class Loop:
|
|||
socket family AF_INET or socket.AF_INET6 depending on host (or
|
||||
family if specified), socket type SOCK_DGRAM.
|
||||
|
||||
reuse_address tells the kernel to reuse a local socket in
|
||||
TIME_WAIT state, without waiting for its natural timeout to
|
||||
expire. If not specified it will automatically be set to True on
|
||||
UNIX.
|
||||
|
||||
reuse_port tells the kernel to allow this endpoint to be bound to
|
||||
the same port as other existing endpoints are bound to, so long as
|
||||
they all set this flag when being created. This option is not
|
||||
|
@ -2965,7 +2965,7 @@ cdef class Loop:
|
|||
'A UDP Socket was expected, got {!r}'.format(sock))
|
||||
if (local_addr or remote_addr or
|
||||
family or proto or flags or
|
||||
reuse_address or reuse_port or allow_broadcast):
|
||||
reuse_port or allow_broadcast):
|
||||
# show the problematic kwargs in exception msg
|
||||
opts = dict(local_addr=local_addr, remote_addr=remote_addr,
|
||||
family=family, proto=proto, flags=flags,
|
||||
|
@ -2982,7 +2982,16 @@ cdef class Loop:
|
|||
udp.open(sock.family, sock.fileno())
|
||||
udp._attach_fileobj(sock)
|
||||
else:
|
||||
reuse_address = bool(reuse_address)
|
||||
if reuse_address is not _unset:
|
||||
if reuse_address:
|
||||
raise ValueError("Passing `reuse_address=True` is no "
|
||||
"longer supported, as the usage of "
|
||||
"SO_REUSEPORT in UDP poses a significant "
|
||||
"security concern.")
|
||||
else:
|
||||
warnings_warn("The *reuse_address* parameter has been "
|
||||
"deprecated as of 0.15.", DeprecationWarning,
|
||||
stacklevel=2)
|
||||
reuse_port = bool(reuse_port)
|
||||
if reuse_port and not has_SO_REUSEPORT:
|
||||
raise ValueError(
|
||||
|
@ -3035,7 +3044,7 @@ cdef class Loop:
|
|||
udp._init(self, lai.ai_family)
|
||||
if reuse_port:
|
||||
self._sock_set_reuseport(udp._fileno())
|
||||
udp._bind(lai.ai_addr, reuse_address)
|
||||
udp._bind(lai.ai_addr)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except BaseException as ex:
|
||||
|
|
Loading…
Reference in New Issue