Endless polling EOF socket
還沒有人認領這個 Issue。
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
Hello,
I have this very simple code to attempt a TCP connection to a given host. The linux machine where I run this has tsocks library installed, to transparently redirect connections over socks server. If the target IP accessed through the socks server refuses the connection, the code will end in an endless unbreakable loop.
def tcp_connect(ip, port):
"""Attempt a TCP connection to the given IP and port."""
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((ip, port))
sock.close()
Timeout has no effect, ctrl+c on the console doesn't break it.
Connection attempt with some command line utility ends correctly.
$ ssh 1.1.1.1
ssh: connect to host 1.1.1.1 port 22: Transport endpoint is not connected
$ ldp telnet 1.1.1.1 22
Trying 1.1.1.1...
telnet: Unable to connect to remote host: Transport endpoint is not connected
I tried running strace to see what happens during that endless loop and this is the result :
getpeername(3, 0x7ffd6c12e3f0, [16]) = -1 ENOTCONN (Transport endpoint is not connected)
connect(3, {sa_family=AF_INET, sin_port=htons(2224), sin_addr=inet_addr("172.17.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
poll([{fd=3, events=POLLOUT}], 1, 5000) = 1 ([{fd=3, revents=POLLOUT}])
connect(3, {sa_family=AF_INET, sin_port=htons(2224), sin_addr=inet_addr("172.17.0.1")}, 16) = 0
sendto(3, "\5\2\0\2", 4, 0, NULL, 0) = 4
recvfrom(3, "\5\0", 2, 0, NULL, NULL) = 2
sendto(3, "\5\1\0\1\225\203f\211\0\26", 10, 0, NULL, 0) = 10
recvfrom(3, 0x55944406ddd8, 10, 0, NULL, NULL) = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "", 10, 0, NULL, NULL) = 0
poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "", 10, 0, NULL, NULL) = 0
poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "", 10, 0, NULL, NULL) = 0
poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "", 10, 0, NULL, NULL) = 0
poll([{fd=3, events=POLLIN}], 1, 5000) = 1 ([{fd=3, revents=POLLIN}])
recvfrom(3, "", 10, 0, NULL, NULL) = 0
<continues until sigkill while hogging 100% CPU>
I don't understand it that much, but LLM seems to believe, that the socket is getting polled despite EOF, which is supposedly an error.
Edit:
For comparison, this is how the strace on that telnet looks like
getpeername(3, 0x7ffd4d54e260, [16]) = -1 ENOTCONN (Transport endpoint is not connected)
connect(3, {sa_family=AF_INET, sin_port=htons(2224), sin_addr=inet_addr("172.17.0.1")}, 16) = 0
sendto(3, "\5\2\0\2", 4, 0, NULL, 0) = 4
recvfrom(3, "\5\0", 2, 0, NULL, NULL) = 2
sendto(3, "\5\1\0\1\225\203f\211\0\26", 10, 0, NULL, 0) = 10
recvfrom(3, "", 10, 0, NULL, NULL) = 0
write(2, "telnet: Unable to connect to rem"..., 78telnet: Unable to connect to remote host: Transport endpoint is not connected
) = 78
close(3) = 0
exit_group(1) = ?
+++ exited with 1 +++
Thank you for your attention.
CPython versions tested on:
3.10
Operating systems tested on:
Linux
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從報告中的 tcp_connect 片段開始,使用 Python 3.10 和 tsocks 在 Linux 上重現該問題,然後將其 strace 與正常運作的 telnet 情況進行比較。追蹤重複 EOF 讀取附近的 socket 和 connect_ex 行為,以確定迴圈是在 CPython 中,還是在透明代理層中。確定了負責該行為的元件,且 issue 有可重現的回歸測試或明確的解決方案,即視為完成。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- networking
- Issue 類型
- 缺陷
- 難度
- 4/5
- 預估耗時
- 3-5 天
- 活躍度
- 冷清
- 描述清晰度
- 需要釐清
- 新手友好度
- 45/100