bpo-27456: Ensure TCP_NODELAY is set on linux (#4231) · python/cpython@e796b2f (original) (raw)
`@@ -82,18 +82,24 @@ def _set_reuseport(sock):
`
82
82
`'SO_REUSEPORT defined but not implemented.')
`
83
83
``
84
84
``
85
``
`-
def _is_stream_socket(sock):
`
86
``
`-
Linux's socket.type is a bitmask that can include extra info
`
87
``
`-
about socket, therefore we can't do simple
`
88
``
`` -
sock_type == socket.SOCK_STREAM
.
``
89
``
`-
return (sock.type & socket.SOCK_STREAM) == socket.SOCK_STREAM
`
``
85
`+
def _is_stream_socket(sock_type):
`
``
86
`+
if hasattr(socket, 'SOCK_NONBLOCK'):
`
``
87
`+
Linux's socket.type is a bitmask that can include extra info
`
``
88
`+
about socket (like SOCK_NONBLOCK bit), therefore we can't do simple
`
``
89
`` +
sock_type == socket.SOCK_STREAM
, see
``
``
90
`+
https://github.com/torvalds/linux/blob/v4.13/include/linux/net.h#L77
`
``
91
`+
for more details.
`
``
92
`+
return (sock_type & 0xF) == socket.SOCK_STREAM
`
``
93
`+
else:
`
``
94
`+
return sock_type == socket.SOCK_STREAM
`
90
95
``
91
96
``
92
``
`-
def _is_dgram_socket(sock):
`
93
``
`-
Linux's socket.type is a bitmask that can include extra info
`
94
``
`-
about socket, therefore we can't do simple
`
95
``
`` -
sock_type == socket.SOCK_DGRAM
.
``
96
``
`-
return (sock.type & socket.SOCK_DGRAM) == socket.SOCK_DGRAM
`
``
97
`+
def _is_dgram_socket(sock_type):
`
``
98
`+
if hasattr(socket, 'SOCK_NONBLOCK'):
`
``
99
`` +
See the comment in _is_stream_socket
.
``
``
100
`+
return (sock_type & 0xF) == socket.SOCK_DGRAM
`
``
101
`+
else:
`
``
102
`+
return sock_type == socket.SOCK_DGRAM
`
97
103
``
98
104
``
99
105
`def _ipaddr_info(host, port, family, type, proto):
`
`@@ -106,14 +112,9 @@ def _ipaddr_info(host, port, family, type, proto):
`
106
112
`host is None:
`
107
113
`return None
`
108
114
``
109
``
`-
if type == socket.SOCK_STREAM:
`
110
``
`-
Linux only:
`
111
``
`-
getaddrinfo() can raise when socket.type is a bit mask.
`
112
``
`-
So if socket.type is a bit mask of SOCK_STREAM, and say
`
113
``
`-
SOCK_NONBLOCK, we simply return None, which will trigger
`
114
``
`-
a call to getaddrinfo() letting it process this request.
`
``
115
`+
if _is_stream_socket(type):
`
115
116
`proto = socket.IPPROTO_TCP
`
116
``
`-
elif type == socket.SOCK_DGRAM:
`
``
117
`+
elif _is_dgram_socket(type):
`
117
118
`proto = socket.IPPROTO_UDP
`
118
119
`else:
`
119
120
`return None
`
`@@ -758,7 +759,7 @@ async def create_connection(self, protocol_factory, host=None, port=None,
`
758
759
`if sock is None:
`
759
760
`raise ValueError(
`
760
761
`'host and port was not specified and no sock specified')
`
761
``
`-
if not _is_stream_socket(sock):
`
``
762
`+
if not _is_stream_socket(sock.type):
`
762
763
`# We allow AF_INET, AF_INET6, AF_UNIX as long as they
`
763
764
`# are SOCK_STREAM.
`
764
765
`# We support passing AF_UNIX sockets even though we have
`
`@@ -808,7 +809,7 @@ async def create_datagram_endpoint(self, protocol_factory,
`
808
809
`allow_broadcast=None, sock=None):
`
809
810
`"""Create datagram connection."""
`
810
811
`if sock is not None:
`
811
``
`-
if not _is_dgram_socket(sock):
`
``
812
`+
if not _is_dgram_socket(sock.type):
`
812
813
`raise ValueError(
`
813
814
`f'A UDP Socket was expected, got {sock!r}')
`
814
815
`if (local_addr or remote_addr or
`
`@@ -1036,7 +1037,7 @@ async def create_server(self, protocol_factory, host=None, port=None,
`
1036
1037
`else:
`
1037
1038
`if sock is None:
`
1038
1039
`raise ValueError('Neither host/port nor sock were specified')
`
1039
``
`-
if not _is_stream_socket(sock):
`
``
1040
`+
if not _is_stream_socket(sock.type):
`
1040
1041
`raise ValueError(f'A Stream Socket was expected, got {sock!r}')
`
1041
1042
`sockets = [sock]
`
1042
1043
``
`@@ -1059,7 +1060,7 @@ async def connect_accepted_socket(self, protocol_factory, sock,
`
1059
1060
` This method is a coroutine. When completed, the coroutine
`
1060
1061
` returns a (transport, protocol) pair.
`
1061
1062
` """
`
1062
``
`-
if not _is_stream_socket(sock):
`
``
1063
`+
if not _is_stream_socket(sock.type):
`
1063
1064
`raise ValueError(f'A Stream Socket was expected, got {sock!r}')
`
1064
1065
``
1065
1066
`transport, protocol = await self._create_connection_transport(
`