`asyncio` does not set `TCP_NODELAY` on macOS
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
Bug report
Bug description:
On macOS, asyncio server silently skips setting TCP_NODELAY on accepted connections.
Reproduce
import asyncio
import socket
async def main():
async def on_connect(reader, writer):
sock = writer.transport.get_extra_info('socket')
nodelay = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
print(f'server side: sock.proto={sock.proto} TCP_NODELAY={nodelay}')
writer.close()
await writer.wait_closed()
srv.close()
srv = await asyncio.start_server(on_connect, '127.0.0.1', 0)
port = srv.sockets[0].getsockname()[1]
reader, writer = await asyncio.open_connection('127.0.0.1', port)
sock = writer.transport.get_extra_info('socket')
nodelay = sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY)
print(f'client side: sock.proto={sock.proto} TCP_NODELAY={nodelay}')
await asyncio.sleep(0.1)
writer.close()
await writer.wait_closed()
await srv.wait_closed()
asyncio.run(main())
| Platform | Side | sock.proto |
TCP_NODELAY |
|---|---|---|---|
| Linux | client | 6 ✅ | 1 ✅ |
| Linux | server | 6 ✅ | 1 ✅ |
| macOS | client | 6 ✅ | 4 ✅ |
| macOS | server | 0 ❌ | 0 ❌ |
Cause
In socket.__init__, CPython tries to detect proto with getsockopt + SO_PROTOCOL and falls back to 0 if SO_PROTOCOL is not supported, which is the case on macOS.
While socket.accept does pass in the proto from listening socket, it is silently overridden to zero by the above logic.
https://github.com/python/cpython/blob/82767780f8de2fc492567ceb6a590101ae3b19ad/Lib/socket.py#L300
asyncio sets TCP_NODELAY only when sock.proto == socket.IPPROTO_TCP, but it is 0 on macOS for the above reason.
Client socket works fine because no fd is passed to socket.__init__ so the proto detection doesn't happen.
CPython versions tested on:
3.13
Operating systems tested on:
macOS, Linux
Linked PRs
- gh-148784
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Revise a implementação vinculada em Modules/socketmodule.c, Lib/socket.py e Lib/asyncio/base_events.py, começando por socket.init e socket.accept. Verifique o PR gh-148784 antes de começar; considera-se concluído quando as conexões aceitas no macOS recebem as informações esperadas do protocolo TCP e o asyncio define TCP_NODELAY de forma consistente com as conexões de cliente.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- c, python
- Domínio
- networking
- Tipo de issue
- Bug
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Status de atividade
- Estagnada
- Clareza
- Claramente especificada
- Facilidade para iniciantes
- 25/100