summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo van Kemenade <hugovk@users.noreply.github.com>2021-09-08 16:58:43 (GMT)
committerGitHub <noreply@github.com>2021-09-08 16:58:43 (GMT)
commit59ea704df7a2fae4559e1e04f7a59d6c40f63657 (patch)
treed465a855c6325d2faeb2486a33d3183058ac6ebf
parenta5610057615779ca6fc75d9e006d2fae644a94d3 (diff)
downloadcpython-59ea704df7a2fae4559e1e04f7a59d6c40f63657.zip
cpython-59ea704df7a2fae4559e1e04f7a59d6c40f63657.tar.gz
cpython-59ea704df7a2fae4559e1e04f7a59d6c40f63657.tar.bz2
bpo-45129 Remove deprecated reuse_address (GH-28207)
Due to significant security concerns, the reuse_address parameter of asyncio.loop.create_datagram_endpoint, deprecated in Python 3.9, is now removed. This is because of the behavior of the socket option SO_REUSEADDR in UDP. Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
-rw-r--r--Doc/library/asyncio-eventloop.rst38
-rw-r--r--Doc/whatsnew/3.11.rst6
-rw-r--r--Lib/asyncio/base_events.py27
-rw-r--r--Lib/test/test_asyncio/test_base_events.py26
-rw-r--r--Misc/NEWS.d/next/Library/2021-09-07-14-27-39.bpo-45129.vXH0gw.rst6
5 files changed, 33 insertions, 70 deletions
diff --git a/Doc/library/asyncio-eventloop.rst b/Doc/library/asyncio-eventloop.rst
index 147fb2b..c4408f1 100644
--- a/Doc/library/asyncio-eventloop.rst
+++ b/Doc/library/asyncio-eventloop.rst
@@ -493,24 +493,9 @@ Opening network connections
.. coroutinemethod:: loop.create_datagram_endpoint(protocol_factory, \
local_addr=None, remote_addr=None, *, \
family=0, proto=0, flags=0, \
- reuse_address=None, reuse_port=None, \
+ reuse_port=None, \
allow_broadcast=None, sock=None)
- .. note::
- The parameter *reuse_address* is no longer supported, as using
- :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for
- UDP. Explicitly passing ``reuse_address=True`` will raise an exception.
-
- When multiple processes with differing UIDs assign sockets to an
- identical UDP socket address with ``SO_REUSEADDR``, incoming packets can
- become randomly distributed among the sockets.
-
- For supported platforms, *reuse_port* can be used as a replacement for
- similar functionality. With *reuse_port*,
- :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically
- prevents processes with differing UIDs from assigning sockets to the same
- socket address.
-
Create a datagram connection.
The socket family can be either :py:data:`~socket.AF_INET`,
@@ -557,16 +542,31 @@ Opening network connections
:ref:`UDP echo server protocol <asyncio-udp-echo-server-protocol>` examples.
.. versionchanged:: 3.4.4
- The *family*, *proto*, *flags*, *reuse_address*, *reuse_port,
+ The *family*, *proto*, *flags*, *reuse_address*, *reuse_port*,
*allow_broadcast*, and *sock* parameters were added.
.. versionchanged:: 3.8.1
- The *reuse_address* parameter is no longer supported due to security
- concerns.
+ The *reuse_address* parameter is no longer supported, as using
+ :py:data:`~sockets.SO_REUSEADDR` poses a significant security concern for
+ UDP. Explicitly passing ``reuse_address=True`` will raise an exception.
+
+ When multiple processes with differing UIDs assign sockets to an
+ identical UDP socket address with ``SO_REUSEADDR``, incoming packets can
+ become randomly distributed among the sockets.
+
+ For supported platforms, *reuse_port* can be used as a replacement for
+ similar functionality. With *reuse_port*,
+ :py:data:`~sockets.SO_REUSEPORT` is used instead, which specifically
+ prevents processes with differing UIDs from assigning sockets to the same
+ socket address.
.. versionchanged:: 3.8
Added support for Windows.
+ .. versionchanged:: 3.11
+ The *reuse_address* parameter, disabled since Python 3.9.0, 3.8.1,
+ 3.7.6 and 3.6.10, has been entirely removed.
+
.. coroutinemethod:: loop.create_unix_connection(protocol_factory, \
path=None, *, ssl=None, sock=None, \
server_hostname=None, ssl_handshake_timeout=None)
diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst
index 55ba832..64bdc0f 100644
--- a/Doc/whatsnew/3.11.rst
+++ b/Doc/whatsnew/3.11.rst
@@ -254,6 +254,12 @@ Removed
Use ``bdist_wheel`` (wheel packages) instead.
(Contributed by Hugo van Kemenade in :issue:`45124`.)
+* Due to significant security concerns, the *reuse_address* parameter of
+ :meth:`asyncio.loop.create_datagram_endpoint`, disabled in Python 3.9, is
+ now entirely removed. This is because of the behavior of the socket option
+ ``SO_REUSEADDR`` in UDP.
+ (Contributed by Hugo van Kemenade in :issue:`45129`.)
+
* Remove :meth:`__getitem__` methods of
:class:`xml.dom.pulldom.DOMEventStream`, :class:`wsgiref.util.FileWrapper`
and :class:`fileinput.FileInput`, deprecated since Python 3.9.
diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py
index 125d32d..054d7b4 100644
--- a/Lib/asyncio/base_events.py
+++ b/Lib/asyncio/base_events.py
@@ -66,10 +66,6 @@ _HAS_IPv6 = hasattr(socket, 'AF_INET6')
# Maximum timeout passed to select to avoid OS limitations
MAXIMUM_SELECT_TIMEOUT = 24 * 3600
-# Used for deprecation and removal of `loop.create_datagram_endpoint()`'s
-# *reuse_address* parameter
-_unset = object()
-
def _format_handle(handle):
cb = handle._callback
@@ -1235,7 +1231,7 @@ class BaseEventLoop(events.AbstractEventLoop):
async def create_datagram_endpoint(self, protocol_factory,
local_addr=None, remote_addr=None, *,
family=0, proto=0, flags=0,
- reuse_address=_unset, reuse_port=None,
+ reuse_port=None,
allow_broadcast=None, sock=None):
"""Create datagram connection."""
if sock is not None:
@@ -1248,7 +1244,7 @@ class BaseEventLoop(events.AbstractEventLoop):
# show the problematic kwargs in exception msg
opts = dict(local_addr=local_addr, remote_addr=remote_addr,
family=family, proto=proto, flags=flags,
- reuse_address=reuse_address, reuse_port=reuse_port,
+ reuse_port=reuse_port,
allow_broadcast=allow_broadcast)
problems = ', '.join(f'{k}={v}' for k, v in opts.items() if v)
raise ValueError(
@@ -1311,19 +1307,6 @@ class BaseEventLoop(events.AbstractEventLoop):
exceptions = []
- # bpo-37228
- 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 3.5.10 and is scheduled "
- "for removal in 3.11.", DeprecationWarning,
- stacklevel=2)
-
for ((family, proto),
(local_address, remote_address)) in addr_pairs_info:
sock = None
@@ -1407,7 +1390,6 @@ class BaseEventLoop(events.AbstractEventLoop):
sock=None,
backlog=100,
ssl=None,
- reuse_address=None,
reuse_port=None,
ssl_handshake_timeout=None,
start_serving=True):
@@ -1438,8 +1420,6 @@ class BaseEventLoop(events.AbstractEventLoop):
raise ValueError(
'host/port and sock can not be specified at the same time')
- if reuse_address is None:
- reuse_address = os.name == 'posix' and sys.platform != 'cygwin'
sockets = []
if host == '':
hosts = [None]
@@ -1469,9 +1449,6 @@ class BaseEventLoop(events.AbstractEventLoop):
af, socktype, proto, exc_info=True)
continue
sockets.append(sock)
- if reuse_address:
- sock.setsockopt(
- socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
if reuse_port:
_set_reuseport(sock)
# Disable IPv4/IPv6 dual stack support (enabled by
diff --git a/Lib/test/test_asyncio/test_base_events.py b/Lib/test/test_asyncio/test_base_events.py
index adc7bd4..b522fac 100644
--- a/Lib/test/test_asyncio/test_base_events.py
+++ b/Lib/test/test_asyncio/test_base_events.py
@@ -1794,32 +1794,6 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
self.loop.run_until_complete(protocol.done)
self.assertEqual('CLOSED', protocol.state)
- 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
-
- coro = self.loop.create_datagram_endpoint(
- lambda: MyDatagramProto(create_future=True, 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
-
- coro = self.loop.create_datagram_endpoint(
- lambda: MyDatagramProto(create_future=True, loop=self.loop),
- local_addr=('127.0.0.1', 0),
- reuse_address=False)
-
- with self.assertWarns(DeprecationWarning):
- transport, protocol = self.loop.run_until_complete(coro)
- transport.close()
- self.loop.run_until_complete(protocol.done)
- self.assertEqual('CLOSED', protocol.state)
-
@patch_socket
def test_create_datagram_endpoint_nosoreuseport(self, m_socket):
del m_socket.SO_REUSEPORT
diff --git a/Misc/NEWS.d/next/Library/2021-09-07-14-27-39.bpo-45129.vXH0gw.rst b/Misc/NEWS.d/next/Library/2021-09-07-14-27-39.bpo-45129.vXH0gw.rst
new file mode 100644
index 0000000..5ba6721
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-09-07-14-27-39.bpo-45129.vXH0gw.rst
@@ -0,0 +1,6 @@
+Due to significant security concerns, the *reuse_address* parameter of
+:meth:`asyncio.loop.create_datagram_endpoint`, disabled in Python 3.9, is
+now entirely removed. This is because of the behavior of the socket option
+``SO_REUSEADDR`` in UDP.
+
+Patch by Hugo van Kemenade.