]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Issue #28174: Handle when SO_REUSEPORT isn't properly supported (asyncio)
authorYury Selivanov <yury@magic.io>
Thu, 15 Sep 2016 19:45:07 +0000 (15:45 -0400)
committerYury Selivanov <yury@magic.io>
Thu, 15 Sep 2016 19:45:07 +0000 (15:45 -0400)
Patch by Seth Michael Larson.

Lib/asyncio/base_events.py
Lib/test/test_asyncio/test_base_events.py
Misc/NEWS

index 8d926dc901edd645fe3fb4a43556fdcdff119a46..03935ea94ba53018ac7e624384d6fa1805c8ab85 100644 (file)
@@ -76,6 +76,17 @@ def _format_pipe(fd):
         return repr(fd)
 
 
+def _set_reuseport(sock):
+    if not hasattr(socket, 'SO_REUSEPORT'):
+        raise ValueError('reuse_port not supported by socket module')
+    else:
+        try:
+            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+        except OSError:
+            raise ValueError('reuse_port not supported by socket module, '
+                             'SO_REUSEPORT defined but not implemented.')
+
+
 # Linux's sock.type is a bitmask that can include extra info about socket.
 _SOCKET_TYPE_MASK = 0
 if hasattr(socket, 'SOCK_NONBLOCK'):
@@ -873,12 +884,7 @@ class BaseEventLoop(events.AbstractEventLoop):
                         sock.setsockopt(
                             socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                     if reuse_port:
-                        if not hasattr(socket, 'SO_REUSEPORT'):
-                            raise ValueError(
-                                'reuse_port not supported by socket module')
-                        else:
-                            sock.setsockopt(
-                                socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
+                        _set_reuseport(sock)
                     if allow_broadcast:
                         sock.setsockopt(
                             socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
@@ -1001,12 +1007,7 @@ class BaseEventLoop(events.AbstractEventLoop):
                         sock.setsockopt(
                             socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
                     if reuse_port:
-                        if not hasattr(socket, 'SO_REUSEPORT'):
-                            raise ValueError(
-                                'reuse_port not supported by socket module')
-                        else:
-                            sock.setsockopt(
-                                socket.SOL_SOCKET, socket.SO_REUSEPORT, True)
+                        _set_reuseport(sock)
                     # Disable IPv4/IPv6 dual stack support (enabled by
                     # default on Linux) which makes a single socket
                     # listen on both address families.
index 0efdc202df135ae438513c8a61d74c7c87b28f42..43ebdc8b2cba222a7b45bdd29c882fe9ac41e2cf 100644 (file)
@@ -1370,6 +1370,17 @@ class BaseEventLoopWithSelectorTests(test_utils.TestCase):
 
         self.assertRaises(ValueError, self.loop.run_until_complete, f)
 
+    @patch_socket
+    def test_create_server_soreuseport_only_defined(self, m_socket):
+        m_socket.getaddrinfo = socket.getaddrinfo
+        m_socket.socket.return_value = mock.Mock()
+        m_socket.SO_REUSEPORT = -1
+
+        f = self.loop.create_server(
+            MyProto, '0.0.0.0', 0, reuse_port=True)
+
+        self.assertRaises(ValueError, self.loop.run_until_complete, f)
+
     @patch_socket
     def test_create_server_cant_bind(self, m_socket):
 
index 0ebf5408449a3c114f82272eac103abca601a53f..b63aafd96b6c0726385c7e5e7989d933658ae669 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -266,6 +266,9 @@ Library
 - Issue #27906: Fix socket accept exhaustion during high TCP traffic.
   Patch by Kevin Conway.
 
+- Issue #28174: Handle when SO_REUSEPORT isn't properly supported.
+  Patch by Seth Michael Larson.
+
 IDLE
 ----