Endless polling EOF socket
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 77.2k
- Forks
- 35.9k
- PR merge metrics
- PR metrics pending
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the tcp_connect snippet in the report and reproduce it on Linux with Python 3.10 and tsocks, then compare its strace with the working telnet case. Trace the socket and connect_ex behavior around repeated EOF reads to determine whether the loop is in CPython or the transparent proxy layer. Done means the responsible behavior is identified and the issue has a reproducible regression test or clear resolution.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 45/100