@@ -82,18 +82,24 @@ def _set_reuseport(sock):
8282 'SO_REUSEPORT defined but not implemented.' )
8383
8484
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
9095
9196
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
97103
98104
99105def _ipaddr_info (host , port , family , type , proto ):
@@ -106,14 +112,9 @@ def _ipaddr_info(host, port, family, type, proto):
106112 host is None :
107113 return None
108114
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 ):
115116 proto = socket .IPPROTO_TCP
116- elif type == socket . SOCK_DGRAM :
117+ elif _is_dgram_socket ( type ) :
117118 proto = socket .IPPROTO_UDP
118119 else :
119120 return None
@@ -758,7 +759,7 @@ async def create_connection(self, protocol_factory, host=None, port=None,
758759 if sock is None :
759760 raise ValueError (
760761 '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 ):
762763 # We allow AF_INET, AF_INET6, AF_UNIX as long as they
763764 # are SOCK_STREAM.
764765 # We support passing AF_UNIX sockets even though we have
@@ -808,7 +809,7 @@ async def create_datagram_endpoint(self, protocol_factory,
808809 allow_broadcast = None , sock = None ):
809810 """Create datagram connection."""
810811 if sock is not None :
811- if not _is_dgram_socket (sock ):
812+ if not _is_dgram_socket (sock . type ):
812813 raise ValueError (
813814 f'A UDP Socket was expected, got { sock !r} ' )
814815 if (local_addr or remote_addr or
@@ -1036,7 +1037,7 @@ async def create_server(self, protocol_factory, host=None, port=None,
10361037 else :
10371038 if sock is None :
10381039 raise ValueError ('Neither host/port nor sock were specified' )
1039- if not _is_stream_socket (sock ):
1040+ if not _is_stream_socket (sock . type ):
10401041 raise ValueError (f'A Stream Socket was expected, got { sock !r} ' )
10411042 sockets = [sock ]
10421043
@@ -1059,7 +1060,7 @@ async def connect_accepted_socket(self, protocol_factory, sock,
10591060 This method is a coroutine. When completed, the coroutine
10601061 returns a (transport, protocol) pair.
10611062 """
1062- if not _is_stream_socket (sock ):
1063+ if not _is_stream_socket (sock . type ):
10631064 raise ValueError (f'A Stream Socket was expected, got { sock !r} ' )
10641065
10651066 transport , protocol = await self ._create_connection_transport (
0 commit comments