summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/selector_events.py
diff options
context:
space:
mode:
authorVincent Michel <vxgmichel@gmail.com>2019-05-07 17:18:49 (GMT)
committerMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-05-07 17:18:49 (GMT)
commit63deaa5b70108ef441c57728322da6b4321db4fc (patch)
tree79e5e4911d6a0d6460d36355d394c969b98f437b /Lib/asyncio/selector_events.py
parent91cc01f40eec03ece2d6b04ad9ea786e77707d8d (diff)
downloadcpython-63deaa5b70108ef441c57728322da6b4321db4fc.zip
cpython-63deaa5b70108ef441c57728322da6b4321db4fc.tar.gz
cpython-63deaa5b70108ef441c57728322da6b4321db4fc.tar.bz2
bpo-31922: Do not connect UDP sockets when broadcast is allowed (GH-423)
*Moved from python/asyncio#493.* This PR fixes issue python/asyncio#480, as explained in [this comment](https://github.com/python/asyncio/issues/480#issuecomment-278703828). The `_SelectorDatagramTransport.sendto` method has to be modified ~~so `_sock.sendto` is used in all cases (because it is tricky to reliably tell if the socket is connected or not). Could that be an issue for connected sockets?~~ *EDIT* ... so `_sock.send` is used only if `_sock` is connected. It also protects `socket.getsockname` against `OSError` in `_SelectorTransport`. This might happen on Windows if the socket is not connected (e.g. for UDP broadcasting). https://bugs.python.org/issue31922
Diffstat (limited to 'Lib/asyncio/selector_events.py')
-rw-r--r--Lib/asyncio/selector_events.py17
1 files changed, 11 insertions, 6 deletions
diff --git a/Lib/asyncio/selector_events.py b/Lib/asyncio/selector_events.py
index 93b6889..2996821 100644
--- a/Lib/asyncio/selector_events.py
+++ b/Lib/asyncio/selector_events.py
@@ -587,7 +587,10 @@ class _SelectorTransport(transports._FlowControlMixin,
def __init__(self, loop, sock, protocol, extra=None, server=None):
super().__init__(extra, loop)
self._extra['socket'] = sock
- self._extra['sockname'] = sock.getsockname()
+ try:
+ self._extra['sockname'] = sock.getsockname()
+ except OSError:
+ self._extra['sockname'] = None
if 'peername' not in self._extra:
try:
self._extra['peername'] = sock.getpeername()
@@ -976,9 +979,11 @@ class _SelectorDatagramTransport(_SelectorTransport):
if not data:
return
- if self._address and addr not in (None, self._address):
- raise ValueError(
- f'Invalid address: must be None or {self._address}')
+ if self._address:
+ if addr not in (None, self._address):
+ raise ValueError(
+ f'Invalid address: must be None or {self._address}')
+ addr = self._address
if self._conn_lost and self._address:
if self._conn_lost >= constants.LOG_THRESHOLD_FOR_CONNLOST_WRITES:
@@ -989,7 +994,7 @@ class _SelectorDatagramTransport(_SelectorTransport):
if not self._buffer:
# Attempt to send it right away first.
try:
- if self._address:
+ if self._extra['peername']:
self._sock.send(data)
else:
self._sock.sendto(data, addr)
@@ -1012,7 +1017,7 @@ class _SelectorDatagramTransport(_SelectorTransport):
while self._buffer:
data, addr = self._buffer.popleft()
try:
- if self._address:
+ if self._extra['peername']:
self._sock.send(data)
else:
self._sock.sendto(data, addr)